Opens an external site in a new window
Mental Health Awareness Month
“Community”
RODNEY LAB
  • Home
  • Plus +
  • Newsletter
  • Links
  • Profile
RODNEY LAB
  • Home
  • Plus +
  • Newsletter
  • Links

SvelteKit GraphQL Type Generation # SvelteKit GraphQL Type Generation #

blurry low resolution placeholder image SvelteKit GraphQL Type Generation
  1. Home Rodney Lab Home
  2. Blog Posts Rodney Lab Blog Posts
  3. SvelteKit SvelteKit Blog Posts
<PREVIOUS POST
NEXT POST >
LATEST POST >>

SvelteKit GraphQL Type Generation #

Updated 2 years ago
6 minute read
Gunning Fog Index: 6.8
2 comments
Content by Rodney
blurry low resolution placeholder image Author Image: Rodney from Rodney Lab
SHARE:

💫 GraphQL with TypeScript and SvelteKit #

In this post, we look at how you can do automatic SvelteKit GraphQL type generation. If that means nothing, read on and hopefully, by the end it makes sense! TypeScript builds on JavaScript to add variable types (like you see in Rust, C++ or Java), making it easier to spot mistakes in your code. Adding types to TypesScript code can get old quickly! GraphQL is a typed language, which means you just have to reference the GraphQL schema in the right way to be able to generate types automatically for your TypeScript code base.

Using the graphql-codegen tool, we will see how you can generate a single file containing all the types from the GraphQL API you are using. Then, when you run a query, you will just need to import the type from that file. If you already use TypeScript you know that can save you a lot of time. We'll get autocompletion and all the other benefits of using TypeScript.

🧱 What are we Building? #

This post follows on from a recent post on SvelteKit GraphQL queries using fetch only. However, you can use you the same tool we describe if you are working in Apollo Client on your SvelteKit site.

Please enable JavaScript to watch the video 📼

SvelteKit GraphQL Queries: What we're Building

Rather than build a new site, we will carry on with the site from the post on SvelteKit queries using fetch only. In that post, we queried a public GraphQL API to get up-to-date currency exchange rates. We will use the site built there as a starting point and see how you can generate TypeScript types using codegen even when your API needs authorization credentials. If that sounds exciting, then let's crack on!

🧑🏽‍🎓 How to Generate Types in SvelteKit using a GraphQL API #

Let's work through the steps to generate our types and then use them in our code to check all is well. We are using the earlier mentioned post as a staring point, though the instructions will be similar for another existing project. So follow along with your own project if you prefer.

SvelteKit GraphQL Type Generation #

  1. Let’s start by installing packages. The main package is graphql-codegen-svelte-apollo . The official docs recommend installing the graphql dependency, though I was getting a version conflict when I did install it, and it seems to work well without:
        
    pnpm install -D graphql-codegen-svelte-apollo \
    @graphql-codegen/cli @graphql-codegen/typescript \
    @graphql-codegen/typescript-operations
  2. Next, we need to create a codegen.json config file. You can generate this automatically (by running pnpm exec grapql-codegen init) if you have a basic use case, though you will still probably need to add the graphql-codegen-svelte-apollo plugin to the config manually. Instead, because we need to add authorization credentials to the config, we will create it manually here. Create the codegen.json file in the project's root directory and paste in the following content:
    codegen.json
    json
        
    1 {
    2 "overwrite": true,
    3 "schema": {
    4 "https://swop.cx/graphql": {
    5 "headers": {
    6 "Authorization": "ApiKey ${SWOP_API_KEY}"
    7 }
    8 }
    9 },
    10 "generates": {
    11 "src/lib/generated/graphql.ts": {
    12 "plugins": ["typescript", "typescript-operations", "graphql-codegen-svelte-apollo"]
    13 }
    14 }
    15 }
    Notice in line 6 we include an authorization header, which will contain our credentials for the API. If you are using another API which does not need credentials, just replace lines 3–8 with "schema": "https://example.com/graphql".

    You need to make sure SWOP_API_KEY is defined in your .env file.
  3. We are almost done. Next, we need to add a new generation script to package.json :
    package.json
    json
        
    4 "scripts": {
    5 "dev": "svelte-kit dev -p 3030",
    6 "build": "svelte-kit build",
    7 "preview": "svelte-kit preview -p 3030",
    8 "check": "svelte-check --tsconfig ./tsconfig.json",
    9 "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
    10 "lint": "prettier --ignore-path .gitignore --check --plugin=prettier-plugin-svelte . && eslint --ignore-path .gitignore .",
    11 "prettier:check": "prettier --check --plugin=prettier-plugin-svelte .",
    12 "format": "prettier --ignore-path .gitignore --write --plugin=prettier-plugin-svelte .",
    13 "gen": "export $(grep SWOP_API_KEY .env | xargs) && graphql-codegen --config codegen.json && prettier --write src/lib/generated/graphql.ts"
    14 },
    Conveniently, this is doing three things for us. First, it reads the API key from the .env file, making it available in the next step. I have tested this on macOS. I would expect it to work on Linux and other UNIX-based systems. I'm not sure how to do this on Windows. Please drop comments below if you are using Linux/Unix or Windows and get it to work, so I can update. Secondly, we actually generate the types, output to src/lib/generated/graphql.ts. Finally, we format the types file with prettier — this saves doing it manually, before committing your code. Change the codegen file name if you generated a YAML file automatically in the previous step.
  4. All that is left to do is to start using the new types, testing everything is working. We'll look at that below. Have a look at the new types generated in src/lib/generated/graphql.ts for now. You will see there are some missing dependencies, but if you are only using this file for types, you can ignore them. Just import using the type keyword, wherever you import one of these new types. For example:
        
    import type { Query, QueryLatestArgs } from '$lib/generated/graphql';

🗳 Poll #

How much do you use TypeScript?
Voting reveals latest results.

🖥 Refactor #

Let’s quickly refactor the previous code, making use of the types. Edit src/routes/query/fx-rates.ts:

src/routes/query/fx-rates.ts
typescript
    
1 import { SWOP_API_KEY } from '$env/static/private';
2 import type { Query, QueryLatestArgs } from '$lib/generated/graphql';
3 import { error } from '@sveltejs/kit';
4 import { print } from 'graphql';
5 import gql from 'graphql-tag';
6 import type { Actions, PageServerLoad } from './$types';
7
8 export async function post({ request }: { request: Request }): Promise<ReturnType<RequestHandler>> {
9 try {
10 const { currencies = ['CAD', 'GBP', 'IDR', 'INR', 'USD'] } = (await request.json()) as {
11 currencies: string[];
12 };
13
14 const query = print(gql`
15 query latestQuery($baseCurrency: String = "EUR", $quoteCurrencies: [String!]) {
16 latest(baseCurrency: $baseCurrency, quoteCurrencies: $quoteCurrencies) {
17 baseCurrency
18 quoteCurrency
19 date
20 quote
21 }
22 }
23 `);
24
25 const variables: QueryLatestArgs = {
26 baseCurrency: 'EUR',
27 quoteCurrencies: currencies
28 };
29
30 const response = await fetch('https://swop.cx/graphql', {
31 method: 'POST',
32 headers: {
33 'Content-Type': 'application/json',
34 Authorization: `ApiKey ${process.env['SWOP_API_KEY']}`
35 },
36 body: JSON.stringify({
37 query,
38 variables
39 })
40 });
41 const data: { data: Query } = await response.json();
42
43 return {
44 body: JSON.stringify({ ...data })
45 };
46 } catch (err) {
47 const error = `Error in /query/fx-rates.json.ts: ${err}`;
48 console.error(error);
49 return {
50 status: 500,
51 body: error
52 };
53 }
54 }

For syntax highlighting, we wrapped the query in a gql tag. Although that gives us the highlighting, it changes the type, and we need the query as a string to pass to the API. To convert it back to a string, we use the print function imported from graphql. You can get syntax highlighting on gql tags (in VS Code) by installing the VS Code GraphQL Extension . Thanks to Mário Monteiro for the tip.

Then finally, we can refactor src/routes/index.svelte:

src/routes/index.svelte
svelte
    
21 <script lang="ts">
22 import '@fontsource/source-sans-pro';
23 import rates from '$lib/shared/stores/rates';
24 import type { Query } from '$lib/generated/graphql';
25
26 export let data: Query;
27 rates.set(data.latest);
28 let newCurrency = '';
29 let submitting = false;
30
31 async function handleSubmit() {
32 try {
33 submitting = true;
34 const response = await fetch('/query/fx-rates.json', {
35 method: 'POST',
36 credentials: 'same-origin',
37 headers: {
38 'Content-Type': 'application/json'
39 },
40 body: JSON.stringify({ currencies: [newCurrency] })
41 });
42 const responseData: { data: Query } = await response.json();
43 const rate = responseData.data.latest[0];
44 submitting = false;
45 rates.set([...$rates, rate]);
46 newCurrency = '';
47 } catch (error) {
48 console.error(`Error in handleSubmit function on /: ${error}`);
49 }
50 }
51 </script>

Please enable JavaScript to watch the video 📼

SvelteKit GraphQL Queries: What we're Building

🙌🏽 SvelteKit GraphQL Type Generation: What we Learned #

In this post, we learned:

  • how to generate TypeScript types automatically from a GraphQL API endpoint;
  • configuring graphql-codegen to use HTTP authorization headers; and
  • how to use environment variable with graphql-codegen.

I do hope there is at least one thing in this article which you can use in your work or a side project. As always, get in touch with feedback if I have missed a trick somewhere!

You can see the full code for this SvelteKit GraphQL queries using fetch project on the Rodney Lab Git Hub repo .

🙏🏽 SvelteKit GraphQL Type Generation: Feedback #

Have you found the post useful? Do you have your own methods for solving this problem? Let me know your solution. Would you like to see posts on another topic instead? Get in touch with ideas for new posts. Also, if you like my writing style, get in touch if I can write some posts for your company site on a consultancy basis. Read on to find ways to get in touch, further below. If you want to support posts similar to this one and can spare a few dollars, euros or pounds, please consider supporting me through Buy me a Coffee.

Finally, feel free to share the post on your social media accounts for all your followers who will find it useful. As well as leaving a comment below, you can get in touch via @askRodney on Twitter and also askRodney on Telegram . Also, see further ways to get in touch with Rodney Lab. I post regularly on SvelteKit as well as other topics. Also, subscribe to the newsletter to keep up-to-date with our latest projects.

Thanks for reading this post. I hope you found it valuable. Please get in touch with your feedback and suggestions for posts you would like to see. Read more about me …

blurry low resolution placeholder image Rodney from Rodney Lab
TAGS:
SVELTEKITGRAPHQLTYPESCRIPT

Likes:

Likes

  • TSR Codes profile avatar
  • JYC profile avatar
  • JYC profile avatar
  • Mirco Veltri profile avatar
  • Michael Zerna profile avatar
  • Webjeda 🛹 profile avatar
  • Dotan Simha profile avatar
Likes provided by Mastodon & X via Webmentions.

Related Posts

blurry low resolution placeholder image SvelteKit GraphQL Queries using fetch Only

SvelteKit GraphQL Queries using fetch Only

sveltekit
graphql
typescript
<PREVIOUS POST
NEXT POST >
LATEST POST >>

Leave a comment …

Your information will be handled in line with our Privacy Policy .

Comments

  • Mário Monteiro

    awesome sveltekit fetch posts, I love your posts, keep the good work in this post I must install graphql and @graphql-codegen/typescript-operations else everything works flawless I install vscode extension ext install GraphQL.vscode-graphql-syntax to use syntax highlight win template literals for ex ```ts const query = `#graphql query latestQuery( $baseCurrency: String = "EUR" $quoteCurrencies: [String!] ... ``` Thanks

    3 years ago
    • Rodney

      Hi Mário! Thanks for your feedback and tips. I really appreciate them.
      2 years ago

Ask for more

1 Nov 2022 — Astro Server-Side Rendering: Edge Search Site
3 Oct 2022 — Svelte eCommerce Site: SvelteKit Snipcart Storefront
1 Sept 2022 — Get Started with SvelteKit Headless WordPress

Copyright © 2020 – 2025 Rodney Johnson. All Rights Reserved. Please read important copyright and intellectual property information.

  • Home
  • Profile
  • Plus +
  • Newsletter
  • Contact
  • Links
  • Terms of Use
  • Privacy Policy
We use cookies  to enhance visitors’ experience. Please click the “Options” button to make your choice.  Learn more here.