Skip to content

Configuration Format ​

All gql.tada tooling is set up using a configuration and plugin entry in your tsconfig.json. This configures both:

Update your tsconfig.json and add a new item to the plugins array on compilerOptions.

json
{
  "compilerOptions": {
    "strict": true,
    "plugins": [
      {
        "name": "@0no-co/graphqlsp",
        "schema": "./schema.graphql"
        "tadaOutputLocation": "./src/graphql-env.d.ts",
      }
    ]
  }
}

The section marked containing schema is what you can populate with Schema Options, as described in the next section. This will set up a default schema for gql.tada to use and the only required options are schema and tadaOutputLocation.

If you have multiple schemas you'd like to use with gql.tada, then you'll instead want to create a schemas array.

json
{
  "compilerOptions": {
    "strict": true,
    "plugins": [
      {
        "name": "@0no-co/graphqlsp",
        "schemas": [
          {
            "name": "your-schema-1",
            "schema": "./schema-1.graphql"
            "tadaOutputLocation": "./src/graphql-env-1.d.ts",
          },
          {
            "name": "your-schema-2",
            "schema": "./schema-2.graphql"
            "tadaOutputLocation": "./src/graphql-env-2.d.ts",
          }
        ]
      }
    ]
  }
}

The name property in each schemas[] entry is arbitrary. It's important that you give each of your schemas a name here, but this can be any name you want and is only used to identify the schema internally and to you in error messages.

Optional Schema Options

Don't worry about setting up more than the required schema and tadaOutputLocation configuration option.

All optional schema options are mostly used by the gql.tada CLI, which will tell you if you're missing any of the extra configuration options. Additionally, to validate your configuration, you can always run the gql.tada doctor CLI command.

Schema Options ​

This section documents all of the schema-specific configuration options. These options are specific to a single schema and are added either under the main plugin config or inside the schemas[] array items.

schema required ​

The schema option specifies how to load your GraphQL schema and currently allows for three different schema formats. It accepts either:

  • a path to a .graphql file containing a schema definition (in GraphQL SDL format)
  • a path to a .json file containing a schema’s introspection query data
  • a URL to a GraphQL API that can be introspected
json
{
  "compilerOptions": {
    "plugins": [
      {
        "name": "@0no-co/graphqlsp",
        "schema": "./schema.graphql"
      }
    ]
  }
}
json
{
  "compilerOptions": {
    "plugins": [
      {
        "name": "@0no-co/graphqlsp",
        "schema": "./introspection.json"
      }
    ]
  }
}
json
{
  "compilerOptions": {
    "plugins": [
      {
        "name": "@0no-co/graphqlsp",
        "schema": "http://localhost:4321/graphql"
      }
    ]
  }
}
json
{
  "compilerOptions": {
    "plugins": [
      {
        "name": "@0no-co/graphqlsp",
        "schema": {
          "url": "http://localhost:4321/graphql",
          "headers": {
            "Accept": "application/graphql-response+json"
          }
        }
      }
    ]
  }
}

This option is used by both the gql.tada CLI and @0no-co/graphqlsp and is required for all diagnostics and in-editor support to work.

Installation

Learn how to configure the schema option


tadaOutputLocation required ​

The tadaOutputLocation specifies the output path to write an output file to, which gql.tada uses to infer GraphQL types.

This option is used by gql.tada and is required for gql.tada type inference to work.

The tadaOutputLocation option accepts two different formats. Either a .d.ts file location, or a .ts file location. Depending on the file extension we specify, two different formats are used to save the introspection result. When the option only specifies a directory, a introspection.d.ts file will automatically be written to the output directory.

Format 1 — .d.ts file ​

When writing a .d.ts file, @0no-co/graphqlsp will create a declaration file that automatically declares a setupSchema interface on gql.tada that, via declaration merging in TypeScript, configures gql.tada to use a schema project-wide for typings.

The resulting file will have the following shape:

ts
export type introspection = {
  __schema: { /*...*/ };
};

import * as gqlTada from 'gql.tada';

declare module 'gql.tada' {
  interface setupSchema {
    introspection: introspection;
  }
}

If we want to now customize scalars, for instance, we’ll need to create our own graphql() function by using the introspection type with gql.tada’s initGraphQLTada<>() function:

ts
import { initGraphQLTada } from 'gql.tada';
import type { introspection } from './graphql-env.d.ts';

export const graphql = initGraphQLTada<{
  introspection: introspection;
  scalars: {
    DateTime: string;
    JSON: any;
  };
}>();

Format 2 — .ts file ​

WARNING

We strongly recommend you to use the .d.ts format instead. While it's less reusable, the format will be more efficient and increase TypeScript inference performance. You will still be able to import the introspection type from the .d.ts file.

When writing a .ts file instead, @0no-co/graphqlsp will create a regular TypeScript file that exports an introspection object, which is useful if we’re planning on re-using the introspection data during runtime.

The resulting file will have the following shape:

ts
const introspection = {
  __schema: { /*...*/ },
} as const;

export { introspection };

Hence, with this format it’s required to import the introspection and to create a graphql() function using the initGraphQLTada<>() function. The introspection type won’t be set up project-wide, since the .ts output from @0no-co/graphqlsp doesn’t contain a declare module declaration.

Installation

Learn how to configure the tadaOutputLocation option


tadaTurboLocation ​

The tadaOutputLocation specifies the output path that the gql.tada turbo command will write the type cache output file to.

Type cache files are .d.ts files that cache gql.tada's inferred types This means that when you run gql.tada turbo after making your changes, TypeScript will be able to start up and type check your GraphQL documents much more quickly than without the type cache.

CLI Reference

Learn more about the gql.tada turbo command.


tadaPersistedLocation ​

The tadaPersistedLocation specifies the output path that the gql.tada generate persisted command will write the persisted JSON manifest file to.

Persisted manifest files are .json files that contain all GraphQL documents referenced using a graphql.persisted call. This is useful to implement persisted operations, as all documents will be extracted into the manifest file at compile-time.


Global Options ​

This section documents all of the plugin-wide configuration options. These options aren't specific to a single schema and configure either the gql.tada CLI or @0no-co/graphqlsp in general.

trackFieldUsage ​

json
{
  "compilerOptions": {
    "plugins": [
      {
        "name": "@0no-co/graphqlsp",
        "schema": "./schema.graphql"
        "tadaOutputLocation": "./src/graphql-env.d.ts",
        "trackFieldUsage": true
      }
    ]
  }
}

By default, this option is enabled. When enabled, your usage of fields will be tracked as you consume data typed using a GraphQL document.

@0no-co/graphqlsp and the gql.tada check command will issue warnings when any fields in your selection sets aren't used in your TypeScript code.

tsx
import { 
FragmentOf
,
graphql
,
readFragment
} from 'gql.tada';
GraphQLSP: Field 'maxHP is not used.
export const
PokemonItemFragment
=
graphql
(`
fragment PokemonItem on Pokemon { id name maxHP } `); interface Props {
data
:
FragmentOf
<typeof
PokemonItemFragment
>;
} export const
PokemonItem
= ({
data
}: Props) => {
const
pokemon
=
readFragment
(
PokemonItemFragment
,
data
);
return <li></li>; };

In the above example, we add a maxHP field to a fragment that the component’s code does not actually access, which causes a warning to be displayed.

When should trackFieldUsage be disabled?

Usage of any fields is based on heuristics. As such, depending on your coding patterns this warning can sometimes be triggered erroneously and support of more coding patterns is still being expanded.

If you see any false-positive warnings, feel free to disable trackFieldUsage or report the problematic code pattern to us in an issue.


shouldCheckForColocatedFragments ​

json
{
  "compilerOptions": {
    "plugins": [
      {
        "name": "@0no-co/graphqlsp",
        "schema": "./schema.graphql"
        "tadaOutputLocation": "./src/graphql-env.d.ts",
        "shouldCheckForColocatedFragments": true
      }
    ]
  }
}

By default, this option is enabled. When enabled, your imports will be scanned for exported fragments.

@0no-co/graphqlsp and the gql.tada check command will issue warnings when you're missing imports to a GraphQL fragment exported by another module.
This is important to help with fragment co-location as many component modules may export fragments that you should be importing and use in the importer's GraphQL documents.

tsx
import { 
useQuery
} from 'urql';
import {
graphql
} from 'gql.tada';
import {
PokemonItem
} from './PokemonItem';
GraphQLSP: Unused co-located fragment definition(s)
const
PokemonsQuery
=
graphql
(`
query Pokemons($limit: Int = 10) { pokemons(limit: $limit) { id name } } `, []); export const
PokemonList
= () => {
const [
result
] =
useQuery
({
query
:
PokemonsQuery
});
return null; // ... };

In the above example, we add an import to a PokemonItem component. If the file contains a fragment that we have to use in our query a warning is displayed.

When should shouldCheckForColocatedFragments be disabled?

This warning is context-sensitive. It can be very helpful when you're following our recommended fragment co-location patterns. However, if you're not using co-located fragments, or if you have many "mixed" files that contain both components with fragments and other code, this warning can get confusing and annoying.

We recommend you to disable this check if you know that you're not going to follow fragment co-location.