Netlify Connect /

Access data with Netlify Connect

This product is available on Connect Enterprise plans.

Netlify Connect makes it easy to access data from different data sources and types. Instead of having to make multiple API calls to retrieve data from each source, you can make a single query to your data layer’s unified GraphQL API.

Plus, when you connect a site to your data layer, Netlify will automatically rebuild that site when a data source updates. For static sites, this ensures your site has the latest data from your GraphQL API.

This document outlines some GraphQL concepts, how to use the GraphQL sandbox, and how to access data using the GraphQL API.

# GraphQL concepts

Every data layer has a unique GraphQL schema that you use to build your data queries. Netlify automatically keeps the schema up to date as you make changes to your data layer.

You can use standard GraphQL queries and fragments to interact with your data layer. Note that mutations are not currently supported.

Regex is not currently supported

While the GraphQL sandbox includes a regex option for filtering, regex is not currently supported in queries made in the sandbox or made directly to the GraphQL API.

# Use the GraphQL sandbox

The GraphQL sandbox is an isolated environment in the Netlify UI that you can use to build and test GraphQL operations without directly affecting your sites. Netlify creates a unique GraphiQL sandbox for each data layer that you create.

Note that, although you query the GraphQL API from individual sites, the sandbox is only accessible from your team’s Netlify Connect page. Also, any queries you create in the sandbox have to be copied into your code manually.

To access the GraphQL sandbox for a data layer, follow these steps:

  1. Navigate to the page for your team in the Netlify UI.
  2. Select the data layer from the Data layers list.
  3. On the data layer overview page, select GraphQL sandbox.

Example data layer sandbox with a sample query and the query results displayed.

The sandbox consists of three main areas

  • In the left pane, the sandbox menu and sub-sections, including:
    • the GraphiQL explorer, which contains schema fields and types that you can expand and select to build queries with
    • the documentation explorer, which contains the schema reference docs for your data layer
    • the sandbox history, which contains previous queries you have created and automatically saved
  • In the center pane, the area that you build the query in and buttons to run, copy, prettify, and merge fragments into the query.
  • In the right pane, the area that will contain the output when you run a query.

# Review your data layer schema

The sandbox includes a documentation explorer that contains the schema reference docs for your data layer. The explorer makes it easy to review the combined GraphQL schema for your data layer that was made while syncing all of the GraphQL types from your connected data sources.

If you have connected multiple data sources of the same type, such as two Drupal instances, you will notice the type prefix for each source reflected in the schema. This is helpful to know as you start building your queries.

To review your data layer schema in the GraphQL sandbox, select the book icon (labeled “Show Documentation Explorer” for screen readers) to open the documentation explorer and access the reference docs. You can select each type to learn more about all of the included Object types and fields.

Example sandbox with the book icon and reference docs areas highlighted.

# Build and run a query

Queries for Prismic slices must include __typename

To query Prismic slices, you need to explicitly include the __typename field in the query. For more information, refer to the Query Prismic slices section in our troubleshooting tips doc.

To build a query using the GraphQL schema for your data layer, you have two options:

  1. Toggle open the types in the GraphiQL explorer to find the fields to add to your query. Select items as needed and the query in the center section of the sandbox will update to include your selection.

  2. Enter your query directly in the center pane. As you write the query, the sandbox will suggest fields to add based on the schema. You can continue typing or just select the correct suggestion to add it to your query.

You can add more specificity to your query by selecting the filter, limit, skip, and sort options in the explorer and then entering the logic for your modifier either in the left pane or the center pane.

To run the query, press control + enter or select the play icon (labeled “Execute query” for screen readers) in the center pane. The query results will appear in the pane on the right.

Once you have a query that works for you, copy the query into your codebase and use the GraphQL API to request and access this data in your site.

# Save queries for later

When you use the GraphQL sandbox, we automatically save the queries in the sandbox so that you can return to them later. You can find old queries by selecting the history icon (labeled “Show History” for screen readers) in the left pane to open the sandbox history section.

Since the sandbox uses your browser’s localStorage to save the queries, saved queries are only be available to you and in the browser you create them in. Other team members do not have access to your saved queries when they use the sandbox.

To clear all saved queries, select the settings icon (labeled “Open settings dialog” for screen readers) in the bottom left to open the sandbox settings. Then, under Clear storage, select Clear data.

# Use the GraphQL API

Queries for Prismic slices must include __typename

To query Prismic slices, you need to explicitly include the __typename field in the query. For more information, refer to the Query Prismic slices section in our troubleshooting tips doc.

To use data in your site, add code that sends a query to the data layer’s GraphQL API.

For the most part, the code to query the GraphQL API is the same regardless of if you query in a component file or in a function. But, depending on where you query the API, you need to set up your data layer correctly to ensure your site always has access to the latest data.

If you query the API in site code for a static site or a site that uses a framework that caches pages, or you query using edge functions with caching enabled, it’s important to connect your site to your data layer. Connected sites automatically rebuild and redeploy when data changes. By default, a site redeploy automatically clears the cache ensuring that your customers are served the latest data.

Sites that use functions to query during runtime and don’t cache the responses always have access to the latest data, even if the site isn’t connected.

The following table outlines some common options and how they compare:

API request location Query timing Connect your site?
Site code for SSG (static site generation) Build time Yes
Site code for SSR (server-side rendering) powered by Netlify Functions Runtime No
Site code for SSR (server-side rendering) powered by Netlify Edge Functions without caching enabled Runtime No
Site code for frameworks that cache SSR (server-side rendering) pages, such as Remix. These pages are powered by Netlify Edge Functions with caching enabled. Runtime but then cached for each edge node Maybe
Function code Runtime No
Edge function code without caching enabled Runtime No
Edge function code with caching enabled Runtime but then cached for each edge node Maybe

Once you have the GraphQL API URL and an authentication token, there are a number of tools you can use to query the GraphQL API in your code. The examples below use urql to make the same query but in different locations.

Use the GraphQL sandbox to verify types

If you specify a prefix while adding a data source to your data layer, the prefix is added to all types synced from that data source. This impacts the types you use in your queries. You can confirm what the final types are in the GraphQL sandbox.

# Generate an authentication token

You must authenticate all requests to your data layer’s GraphQL API using a token.

To generate an authentication token for your data layer:

  1. Navigate to the page for your team in the Netlify UI.
  2. Select the data layer from the Data layers list, and then select Data layer settings.
  3. On the data layer settings page, select API tokens.
  4. Select Add an API token.
  5. Enter a name for the token and then select Generate token. Netlify will generate a token for you.
  6. Select the clipboard icon to copy your token and then store it in a safe place. To protect your data, you won’t be able to reveal this token again.

Make sure to include the authentication token in the authorization header for all API requests: Authorization: Bearer <YOUR_AUTH_TOKEN>

Keep your authentication token secure

To keep your authentication token secure, we recommend that you store it in an environment variable on Netlify instead of in your repository. You can also avoid revealing the token in the browser by using a Netlify Function or Edge Function to access the variable and query the GraphQL API during runtime.

If you have concerns about security or need to change who has access to your API, you can revoke authentication tokens as needed.

# Find the GraphQL API URL

The API URL is formatted as https://YOUR-DATA-LAYER-KEY-prod.api.netlify-connect.com. Note that the data layer key is different from the data layer ID.

To find the GraphQL API URL for your data layer:

  1. Navigate to the page for your team in the Netlify UI.
  2. Select the data layer from the Data layers list.
  3. Find the API URL at the top of the page.

You can also find the API URL under

.

# Query in site code

Regardless of if your site uses static site generation (SSG) or uses server-side rendering (SSR), the code to query the API is the same.

Here is an example that uses urql to query the API for the id and title of the first 10 nodes under allContentfulAsset. This example accesses an environment variable EXAMPLE_DATA_LAYER_API_TOKEN that we manually created to securely store the authentication token and uses the value in the API request header.

  1. Install @urql/core.

  2. Depending on the architecture of your app, add the following code to the appropriate file to request data before your component is rendered. Make sure to replace the DATA_LAYER_API_URL and the DATA_LAYER_API_TOKEN with the URL and authentication token for your data layer’s GraphQL API. You should also update the query to reflect your schema.

    import { createClient, fetchExchange } from "@urql/core";
    
    const DATA_LAYER_API_URL =
      "https://example-data-layer-prod.api.netlify-connect.com";
    
    const DATA_LAYER_API_TOKEN = process.env.EXAMPLE_DATA_LAYER_API_TOKEN;
    
    const client = createClient({
      url: DATA_LAYER_API_URL,
      fetchOptions: {
        headers: { authorization: `Bearer ${DATA_LAYER_API_TOKEN}` }
      },
      exchanges: [fetchExchange]
    });
    
    const QUERY = `query {
      allContentfulAsset(limit: 10) {
        nodes {
          id
          title
        }
      }
    }`;
    
    const { data } = await client.query(QUERY, {}).toPromise();
    
    import { createClient, fetchExchange } from "@urql/core";
    
    const DATA_LAYER_API_URL =
      "https://example-data-layer-prod.api.netlify-connect.com";
    
    const DATA_LAYER_API_TOKEN = process.env.EXAMPLE_DATA_LAYER_API_TOKEN;
    
    const client = createClient({
      url: DATA_LAYER_API_URL,
      fetchOptions: {
        headers: { authorization: `Bearer ${DATA_LAYER_API_TOKEN}` }
      },
      exchanges: [fetchExchange]
    });
    
    const QUERY = `query {
      allContentfulAsset(limit: 10) {
        nodes {
          id
          title
        }
      }
    }`;
    
    const { data } = await client.query(QUERY, {}).toPromise();
    
  3. Update your component code to use the results returned from the query.

# When to connect a site that queries in site code

If your site uses static site generation (SSG), make sure you add it as a connection to your data layer. When your data layer updates, Netlify automatically rebuilds your site and any static code that includes queries to your GraphQL API receives the latest data.

If your site uses a framework that caches server-side rendered (SSR) pages, such as Remix, and the pages that query the GraphQL API have long cache expiry times, we recommend that you add it as a connection to your data layer. When your data layer updates, Netlify automatically rebuilds and redeploys your site, which by default invalidates the cache.

If your site uses a framework that handles server-side rendering (SSR) with functions or edge functions without caching enabled, they always have access to the latest data. You don’t need to connect your site.

# Query in a function

Here is an example of how to query the API in a function. Every request to this endpoint receives the latest results from the API.

This example uses urql core to query the API for the id and title of the first 10 nodes under allContentfulAsset. This example accesses an environment variable EXAMPLE_DATA_LAYER_API_TOKEN that we manually created to securely store the authentication token and uses the value in the API request header.

  1. Install @urql/core.

  2. Create a function file in the functions directory. For example, YOUR_BASE_DIRECTORY/netlify/functions/get-data.js.

  3. In the file, add the following code to create a function that queries the API and returns the data. Make sure to replace the DATA_LAYER_API_URL and the DATA_LAYER_API_TOKEN with the URL and authentication token for your data layer’s GraphQL API. You should also update the query to reflect your schema.

    // YOUR_BASE_DIRECTORY/netlify/functions/get-data.ts
    
    import { Client, fetchExchange } from '@urql/core';
    
    import type { Handler, HandlerEvent, HandlerContext } from "@netlify/functions";
    
    const handler: Handler = async (event: HandlerEvent, context: HandlerContext) => {
        const DATA_LAYER_API_URL = 'https://example-data-layer-prod.api.netlify-connect.com';
    
        const DATA_LAYER_API_TOKEN = process.env.EXAMPLE_DATA_LAYER_API_TOKEN;
    
        const QUERY = `
          query {
            allContentfulAsset(limit: 10) {
              nodes {
                id
                title
              }
            }
          }
        `;
    
        const client: Client = new Client({
          url: DATA_LAYER_API_URL,
          fetchOptions: { headers: { authorization: `Bearer ${DATA_LAYER_API_TOKEN}`}},
          exchanges: [fetchExchange],
          fetch
        });
    
        const { data } = await client.query(QUERY, {});
    
        return {
          statusCode: 200,
          body: JSON.stringify(data)
        };
    };
    
    export { handler };
    
    // YOUR_BASE_DIRECTORY/netlify/functions/get-data.js
    
    import { Client, fetchExchange } from "@urql/core";
    
    exports.handler = async function() {
      const DATA_LAYER_API_URL =
        "https://example-data-layer-prod.api.netlify-connect.com";
    
      const DATA_LAYER_API_TOKEN = process.env.EXAMPLE_DATA_LAYER_API_TOKEN;
    
      const QUERY = `
          query {
            allContentfulAsset(limit: 10) {
              nodes {
                id
                title
              }
            }
          }
        `;
    
      const client = new Client({
        url: DATA_LAYER_API_URL,
        fetchOptions: {
          headers: { authorization: `Bearer ${DATA_LAYER_API_TOKEN}` }
        },
        exchanges: [fetchExchange],
        fetch
      });
    
      const { data } = await client.query(QUERY, {});
    
      return {
        statusCode: 200,
        body: JSON.stringify(data)
      };
    };
    

When your site makes a request to the endpoint at /.netlify/functions/get-data relative to the base URL of your site, it receives the results of the query. Since the function makes the API request during runtime, it always gets the latest data from your data layer, even if you don’t rebuild your site.

# Query in an edge function

Here is an example of how to query the API in an edge function without caching enabled. Every request to a path that matches the edge function path receives the latest results from the API.

This example uses urql core with the Fetch API to query the API for the id and title of the first 10 nodes under allContentfulAsset. This example accesses an environment variable EXAMPLE_DATA_LAYER_API_TOKEN that we manually created to securely store the authentication token and uses the value in the API request header.

  1. Create an edge function file in the edge functions directory. For example, YOUR_BASE_DIRECTORY/netlify/edge-functions/get-data.js.

  2. In the file, add the following code to create an edge function that queries the API and returns the data. Make sure to replace the DATA_LAYER_API_URL and the DATA_LAYER_API_TOKEN with the URL and authentication token for your data layer’s GraphQL API. You should also update the query to reflect your schema.

    // YOUR_BASE_DIRECTORY/netlify/edge-functions/get-data.ts
    
    import { Client, fetchExchange } from 'https://esm.sh/@urql/core';
    
    import type { Config, Context } from "@netlify/edge-functions";
    
    export default async function handler(req: Request, context: Context) {
        const DATA_LAYER_API_URL = 'https://example-data-layer-prod.api.netlify-connect.com';
    
        const DATA_LAYER_API_TOKEN = Netlify.env.get("EXAMPLE_DATA_LAYER_API_TOKEN");
    
        const QUERY = `
          query {
            allContentfulAsset(limit: 10) {
              nodes {
                id
                title
              }
            }
          }
        `;
    
        const client: Client = new Client({
          url: DATA_LAYER_API_URL,
          fetchOptions: { headers: { authorization: `Bearer ${DATA_LAYER_API_TOKEN}`}},
          exchanges: [fetchExchange],
          fetch
        });
    
        const { data } = await client.query(QUERY, {});
    
        return Response.json(data);
    };
    
    export const config: Config = { path: "/get-data" };
    
    // YOUR_BASE_DIRECTORY/netlify/edge-functions/get-data.js
    
    import { Client, fetchExchange } from "https://esm.sh/@urql/core";
    
    export default async (request, context) => {
      const DATA_LAYER_API_URL =
        "https://example-data-layer-prod.api.netlify-connect.com";
    
      const DATA_LAYER_API_TOKEN = Netlify.env.get(
        "EXAMPLE_DATA_LAYER_API_TOKEN"
      );
    
      const QUERY = `
          query {
            allContentfulAsset(limit: 10) {
              nodes {
                id
                title
              }
            }
          }
        `;
    
      const client = new Client({
        url: DATA_LAYER_API_URL,
        fetchOptions: {
          headers: { authorization: `Bearer ${DATA_LAYER_API_TOKEN}` }
        },
        exchanges: [fetchExchange],
        fetch
      });
    
      const { data } = await client.query(QUERY, {});
    
      return Response.json(data);
    };
    
    export const config = { path: "/get-data" };
    

When your site makes a request to the /get-data path relative to the base URL of your site, it receives the results of the query. Since the edge function makes the API request during runtime and does not cache the results, it always gets the latest data from your data layer, even if you don’t rebuild your site.

# Query in an edge function with caching

If you would like to cache the results of your query at the edge for even faster response times, you can configure an edge function for caching.

When the edge function is called, the initial query for each edge node is made during runtime. The response is then cached on each edge node until the cache expires based on the headers set, is purged manually, or is invalidated with a redeploy. Make sure that you connect your site to your data layer to ensure the cache is updated when your data layer updates — cached responses respect atomic deploys by default.

Here is an example of how to query the API in an edge function with caching enabled. This example uses urql core with the Fetch API to query the API for the id and title of the first 10 nodes under allContentfulAsset.

This example accesses an environment variable EXAMPLE_DATA_LAYER_API_TOKEN that we manually created to securely store the authentication token and uses the value in the API request header. The edge function returns the query results and caching headers that include the s-maxage of 3600.

  1. Create an edge function file in the edge functions directory. For example, YOUR_BASE_DIRECTORY/netlify/edge-functions/get-data.js.

  2. In the file, add the following code to create an edge function that queries the API and returns the data. Make sure to replace the DATA_LAYER_API_URL and the DATA_LAYER_API_TOKEN with the URL and authentication token for your data layer’s GraphQL API. You should also update the query to reflect your schema.

    // YOUR_BASE_DIRECTORY/netlify/edge-functions/get-data.ts
    
    import { Client, fetchExchange } from 'https://esm.sh/@urql/core';
    
    import type { Config, Context } from "@netlify/edge-functions";
    
    export default async function handler(req: Request, context: Context) {
        const DATA_LAYER_API_URL = 'https://example-data-layer-prod.api.netlify-connect.com';
    
        const DATA_LAYER_API_TOKEN = Netlify.env.get("EXAMPLE_DATA_LAYER_API_TOKEN");
    
        const QUERY = `
          query {
            allContentfulAsset(limit: 10) {
              nodes {
                id
                title
              }
            }
          }
        `;
    
        const client: Client = new Client({
          url: DATA_LAYER_API_URL,
          fetchOptions: { headers: { authorization: `Bearer ${DATA_LAYER_API_TOKEN}`}},
          exchanges: [fetchExchange],
          fetch
        });
    
        const { data } = await client.query(QUERY, {});
    
        return Response.json(data, {
            headers: {
                'cache-control': 'public, s-maxage=3600'
            }
        });
    };
    
    export const config: Config = {
        cache: "manual",
        path: "/get-data"
    };
    
    // YOUR_BASE_DIRECTORY/netlify/edge-functions/get-data.js
    
    import { Client, fetchExchange } from "https://esm.sh/@urql/core";
    
    export default async (request, context) => {
      const DATA_LAYER_API_URL =
        "https://example-data-layer-prod.api.netlify-connect.com";
    
      const DATA_LAYER_API_TOKEN = Netlify.env.get(
        "EXAMPLE_DATA_LAYER_API_TOKEN"
      );
    
      const QUERY = `
          query {
            allContentfulAsset(limit: 10) {
              nodes {
                id
                title
              }
            }
          }
        `;
    
      const client = new Client({
        url: DATA_LAYER_API_URL,
        fetchOptions: {
          headers: { authorization: `Bearer ${DATA_LAYER_API_TOKEN}` }
        },
        exchanges: [fetchExchange],
        fetch
      });
    
      const { data } = await client.query(QUERY, {});
    
      return Response.json(data, {
        headers: {
          "cache-control": "public, s-maxage=3600"
        }
      });
    };
    
    export const config = {
      cache: "manual",
      path: "/get-data"
    };
    

When a request is made to the /get-data path relative to the base URL of your site, the results are cached at the individual edge node until the s-maxage has passed or until the site is redeployed.

To avoid inconsistent results across the edge nodes, we recommend that you connect your site to your data layer if your edge function uses a long cache expiry time. Connecting your site ensures that it is redeployed automatically and invalidates all caches when your data layer changes.