Connect /

Access data with Netlify Connect

This feature 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, configure cross-references and 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.

Which data revision is the data layer’s GraphQL API using?

At the top of the data layer’s overview page, you will find information about the data revision that your data layer’s GraphQL API is currently using — including the data revision ID and whether or not the API is using a pinned revision.

This document outlines some GraphQL concepts, how to use the GraphQL sandbox, how to access data using the GraphQL API, and how to use the Connect client for a better user and developer experience.

# GraphQL concepts

Every data revision for a data layer has a unique GraphQL schema that you use to build your data queries. Netlify automatically generates a new data revision to represent the latest schema whenever your data changes.

By default, the GraphQL API and sandbox for your data layer will use the latest data revision unless you pin a different revision. You also have the option to query a specific dataset using the revision’s unique sandbox and API URL.

You can use standard GraphQL queries and fragments to interact with your data. 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, and for each data revision that results from a successful data sync.

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

Use the Connect client to write queries directly in your editor

Use the Connect client to write queries in your code editor and benefit from in-editor feedback, auto-completion, and type hints based on your data layer’s GraphQL schema.

To access the GraphQL sandbox for a 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. On the data layer overview page, select GraphQL sandbox.

This sandbox represents the data revision that your API is currently using.

To access the GraphQL sandbox for a specific data revision:

  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‘s overview page, select Revisions to access the list of available revisions.
  4. Find the revision you want to access, select Options, and then select Open in GraphQL sandbox.

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

At the top of the sandbox, you’ll find the ID of the data revision that the sandbox is using and when that revision was created. There is also an options menu that you can use to pin or unpin the data revision, download the changeset, and copy the data revision’s GraphQL sandbox link or API URL.

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 the data revision
    • 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 the GraphQL schema

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

If you have added 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 the 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

To build a query using the GraphQL schema for a data revision, 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.

Note that saved queries will appear across all versions of the sandbox but the query will only run against and return data for the associated data revision. To confirm which data revision you are querying against, check the data revision ID at the top of 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

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

By default, your data layer’s GraphQL API uses the latest data revision unless you pin a different one. You also have the option to query a specific data revision using the unique API URL for that revision.

For the most part, the code to query a GraphQL API is the same whether 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. Learn more about when to connect your site.

Once you have the GraphQL API URL and an API token, you can write your query. We recommend using the Connect client for in-editor type system support and caching optimizations, but there are a number of other tools you can use to query. The examples below use urql.

Use the GraphQL sandbox or Connect client 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 or by using the Connect client.

# Generate an API token

You must authenticate all requests to your data layer’s GraphQL API using an API token. If your data layer restricts access to certain fields and types using API scopes, the API token must have the required scopes to access that data.

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

Learn how to generate API tokens and scopes in the API authentication doc.

# Find the GraphQL API URL

By default, your data layer’s GraphQL API uses the latest data revision unless you pin a different one.

The API URL is formatted as https://{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

.

If you want to access the GraphQL API for a specific data revision, use the API URL for that revision. Learn how to access the API for a specific data revision.

# Query in site code

Use Connect client if your site uses SSR with caching

For sites that use server-side rendering (SSR) with caching, we recommend querying your data layer’s API with the Connect client to benefit from more efficient caching of dynamic content.

It doesn’t matter 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 API 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 API 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.

To ensure your site always has access to the latest data, review our doc on when 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 API 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 API 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. 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 API 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 API 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.

# Avoid queries in edge functions configured for caching

Since Connect automatically caches data at the network edge, we don’t recommend using an an edge function configured for caching to query the API.

There are no extra performance benefits to gain from using edge function caching on top of the built-in caching in Connect, and it will likely add unnecessary complexity. We recommend that you use an edge function that is not configured for caching instead.

# Use the Connect client

Use the Connect JavaScript client, connect-client, to make requests to your data layer’s GraphQL API for an optimized user and developer experience.

When you use the client, you benefit from the following:

  • Efficient caching of dynamic content on Netlify’s CDN. Instead of invalidating the full cache every time your data changes, you can invalidate only the stale content. This optimizes site performance for your users and is particularly helpful if your site uses a framework with SSR caching.
  • TypeScript type system support, enhanced by gql.tada. Benefit from in-editor feedback, auto-completion, and type hints based on your data layer’s GraphQL schema. This provides a better developer experience and allows you to write queries directly in your site code instead of copying them over from the GraphQL sandbox.

Refer to the readme to learn more about how Connect client supports caching.

# Cache optimization support

While you can use the client with any framework to query the API and get in-editor type system support, the built-in caching optimization is currently only supported for Astro and Next.js.

If you use a different framework with SSR caching, we recommend that you add your own cache management logic using on-demand invalidation.

Alternatively, you can choose to connect your site for a full redeploy and cache invalidation every time your data changes. While it may not be the most efficient option, it ensures you always have the latest data.

# Configure and use the client

As outlined in the connect-client readme, there are three steps to set up and use the client with your site:

  1. Install the client and configure your project.

    If you only want to use the client to query your data layer’s API and to get in-editor type system support, stop here. Otherwise, complete the following steps to set up the client and your data layer to support cache invalidation.

  2. Create a function to handle cache invalidation.

  3. Set up a custom webhook on your data layer.

Once you set up the client and your project, you can use the client to make queries in your site code. The client automatically adds the authorization headers for each request and, if you completed all three steps, manages the data caching as needed.

Ensure the API token has the correct scopes

If your data layer restricts access to certain fields and types using API scopes, make sure the API token you set for the client or pass to the individual query has the required scopes to access that data.

Here is an example of a query in an Astro project:

import { query } from "@netlify/connect-client";
import { graphql } from "../netlify-connect/graphql"; // Note this is a relative path 

const booksQuery = graphql(`
  query books {
    allContentfulBook {
      nodes {
        id: contentful_id
        title
        coverImage {
          url
        }
        author {
          name
        }
      }
    }
  }
`);

export const getBooks = async (Astro: any) => {
  const res = await query(booksQuery, { Astro });
  return res.allContentfulBook.nodes;
};

For detailed instructions, refer to the connect-clientreadme.

# Limitations and billing

  • Cache optimization is only for Next.js and Astro. While you can use the client with any framework to query the API and get in-editor type system support, the built-in caching optimization is currently only supported for Astro and Next.js.
  • Netlify Functions limits and billing apply. Since the client requires you to add a serverless function to your site, you should review the default deployment options and usage and billing documentation for Netlify Functions.

Manage connected sites in Netlify Connect: When to connect a site