Getting started with SvelteKit, Houdini and Grafbase

Getting started with SvelteKit, Houdini and Grafbase

Houdini GraphQL is a fully-featured GraphQL client that seamlessly integrates with SvelteKit. Houdini automatically adds types for any fragment, mutation or query inside your application.

In this guide we'll setup and configure SvelteKit and Houdini to work with your Grafbase backend.

If you've a SvelteKit already you can skip this step.

npm create svelte@latest grafbase-houdini cd grafbase-houdini npm install

Before we begin we'll need to create a GraphQL backend using the Grafbase CLI.

You can initialize a new Grafbase project by using a single command:

npx grafbase init

This will create the file grafbase/schema.graphql in the root of your project.

You will want to open this and replace the contents with the following schema to follow along with the rest of this guide:

type Message @model { author: String! body: String! }

Next run the following to start your development GraphQL backend:

npx grafbase dev

We will now run the Houdini GraphQL init command that will create and update the necessary Svelte files to configure Houdini.

Make sure you have the Grafbase backend running still before you continue.

In the root of your SvelteKit project run the following:

npx houdini@latest init

When asked you will want to use a remote GraphQL API (Yes), and the URL for your API (by default this will be http://localhost:4000/graphql).

In the root of your project run the following:

npm run dev

We will now add a new file +page.gql inside src/routes that contains the following query:

query GetAllMessages { messageCollection(first: 100) { edges { node { id body } } } }

When you save the file you should see that the terminal receives an update similar to:

🎩 ✨ GetAllMessages

This means Houdini is watching for changes, generating the types, and a Svelte "Store" for each of your queries that it uses as it's cache.

Now all that's left to do is update the file src/routes/+page.svelte to export the query GetAllMessages:

<script lang="ts"> import type { PageData } from './$houdini'; export let data: PageData; $: ({ GetAllMessages } = data); </script> <pre>{JSON.stringify($GetAllMessages.data, null, 2)}</pre>

You will see as you begin to type $GetAllMessages.data that you get full intellisense with the typed query we wrote in +page.gql.

GraphQL query typeahead

By this point everything is working as expected, but if your query contains the use of any scalars that aren't part of the official GraphQL specification then you will soon run into issues.

Let's update the +page.gql to include the field createdAt (DateTime) which Grafbase automatically manages:

query GetAllMessages { messageCollection(first: 100) { edges { node { id body createdAt } } } }

Once this file is saved you should see an error similar to:

⚠️ Missing definitions for the following scalars: DateTime Generated types will contain an any type in place of these values. To fix this, provide an equivalent type in your config file: { scalars: { /* in your case, something like */ DateTime: { // <- The GraphQL Scalar type: "YourType_DateTime" // <- The TypeScript type } } }

We can fix this by updating houdini.config.js to include a custom method to correctly handle this value:

/// <references types="houdini-svelte"> /** @type {import('houdini').ConfigFile} */ const config = { watchSchema: { url: 'http://localhost:4000/graphql', }, plugins: { 'houdini-svelte': {}, }, scalars: { Date: { type: 'Date', marshal(val) { return val.toISOString() }, unmarshal(val) { return new Date(val) }, ...config.scalars?.Date, }, }, } export default config

Of course this isn't ideal for every Grafbase user implementing this logic repeatedly so we made a plugin that does it for you.

Install the following:

npm install @grafbase/houdini

Then inside houdini.config.js update the plugins array to include the dependency:

/// <references types="houdini-svelte"> /** @type {import('houdini').ConfigFile} */ const config = { watchSchema: { url: 'http://localhost:4000/graphql', }, plugins: { 'houdini-svelte': {}, '@grafbase/houdini': {}, }, } export default config

That's it! The plugin will automatically handle the marshalling and unmarshalling the values for any custom scalar.

In development, the Grafbase CLI doesn't require requests to be authenticated.

You will need to update src/client.ts to include the current user token in the authorization header with every request:

export default new HoudiniClient({ url: PUBLIC_GRAFBASE_API_URL, fetchParams({ session }) { return { headers: { // Token generated by your auth provider: https://grafbase.com/docs/auth Authorization: `Bearer ${session?.authToken}`, }, } }, })

This token must be a valid JWT generated by your own backend, or an OIDC provider that is configured to work with Grafbase Auth.

This code example shows an example of how you add a token to the session using Form Actions on the server.

Get Started

Build your API of the future now.