{"id":19571813,"url":"https://github.com/datocms/nextjs-with-cache-tags-starter","last_synced_at":"2025-04-27T03:32:48.110Z","repository":{"id":242863948,"uuid":"804445850","full_name":"datocms/nextjs-with-cache-tags-starter","owner":"datocms","description":"Next.js demo project powered by DatoCMS Cache Tags","archived":false,"fork":false,"pushed_at":"2024-08-20T15:57:38.000Z","size":726,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-08-20T18:15:53.781Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://nextjs-starter-datocms.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/datocms.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-22T15:48:59.000Z","updated_at":"2024-08-20T15:57:41.000Z","dependencies_parsed_at":"2024-08-20T18:08:22.010Z","dependency_job_id":null,"html_url":"https://github.com/datocms/nextjs-with-cache-tags-starter","commit_stats":null,"previous_names":["datocms/nextjs-on-vercel-starter","datocms/nextjs-with-cache-tags-starter"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datocms%2Fnextjs-with-cache-tags-starter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datocms%2Fnextjs-with-cache-tags-starter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datocms%2Fnextjs-with-cache-tags-starter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datocms%2Fnextjs-with-cache-tags-starter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/datocms","download_url":"https://codeload.github.com/datocms/nextjs-with-cache-tags-starter/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224057397,"owners_count":17248476,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T06:20:11.915Z","updated_at":"2025-04-27T03:32:48.103Z","avatar_url":"https://github.com/datocms.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!--datocms-autoinclude-header start--\u003e\n\n\u003ca href=\"https://www.datocms.com/\"\u003e\u003cimg src=\"https://www.datocms.com/images/full_logo.svg\" height=\"60\"\u003e\u003c/a\u003e\n\n👉 [Visit the DatoCMS homepage](https://www.datocms.com) or see [What is DatoCMS?](#what-is-datocms)\n\n---\n\n\u003c!--datocms-autoinclude-header end--\u003e\n\n# Next.js + DatoCMS Cache Tags\n\nEverything you need to know to build a Next.js project powered by DatoCMS Cache Tags to achieve the perfect balance of performance, efficiency, and real-time updates.\n\n\u003cimg src=\"https://github.com/datocms/nextjs-with-cache-tags-starter/raw/main/images/browser.png\" /\u003e\n\n## Table of Contents\n\n- [Table of Contents](#table-of-contents)\n- [Getting Started](#getting-started)\n  - [Step 1: Clone the DatoCMS project](#step-1-clone-the-datocms-project)\n  - [Step 2: Environment variables](#step-2-environment-variables)\n      - [`PUBLIC_DATOCMS_API_TOKEN`](#public_datocms_api_token)\n      - [`WEBHOOK_TOKEN`](#webhook_token)\n      - [`TURSO_DATABASE_URL`, `TURSO_AUTH_TOKEN`](#turso_database_url-turso_auth_token)\n  - [Step 3: Install dependencies and download the DatoCMS GraphQL Schema](#step-3-install-dependencies-and-download-the-datocms-graphql-schema)\n  - [Step 4: Run development server](#step-4-run-development-server)\n- [Deployment](#deployment)\n- [Useful resources to navigate the code](#useful-resources-to-navigate-the-code)\n  - [Execution of GraphQL queries](#execution-of-graphql-queries)\n  - [\"Cache Tags Invalidation\" webhook](#cache-tags-invalidation-webhook)\n\n## Getting Started\n\n### Step 1: Clone the DatoCMS project\n\nStart by pressing this button to create a new project on DatoCMS containing the data expected by this project:\n\n[![Clone DatoCMS project](https://dashboard.datocms.com/clone/button.svg)](https://dashboard.datocms.com/clone?projectId=23796\u0026name=Next.js+%2B+Cache+Tags)\n\n### Step 2: Environment variables\n\nUse `.env.local.example` file as a starting point:\n\n```bash\ncp .env.local.example .env.local\n```\n\nNow open `.env.local` and start populating the variables:\n\n##### `PUBLIC_DATOCMS_API_TOKEN`\n\nThe \"GraphQL API Token\" from the DatoCMS project you just created. [Learn to find/create an API token](https://www.datocms.com/docs/content-delivery-api/authentication).\n\n##### `WEBHOOK_TOKEN`\n\nAny secure random string. It will be used to authenticate the webhook requests that come from DatoCMS.\n\n##### `TURSO_DATABASE_URL`, `TURSO_AUTH_TOKEN`\n\nSimply click the following button to create and initialize a Turso database with the expected schema (sign up or log in to Turso is required):\n\n[![Create a database with Turso](https://sqlite.new/button)](https://sqlite.new?dump=https%3A//raw.githubusercontent.com/datocms/nextjs-with-cache-tags-starter/main/schema.sql)\n\nCopy the database URL and use it to fill the `TURSO_DATABASE_URL` environment variable.\n\nAlso create a token for the database, with no expiration and read/write permissions: copy and use it for the `TURSO_AUTH_TOKEN` variable.\n\nWe selected Turso because it's an incredibly cost-effective solution and is compatible with any hosting service. However, any other storage solution would be just as effective due to the simplicity of the saved data.\n\n### Step 3: Install dependencies and download the DatoCMS GraphQL Schema\n\nSimply run `npm install` (or the equivalent command for your package manager of choice): a `schema.graphql` will be generated.\n\n### Step 4: Run development server\n\nNow you can run the development server:\n\n```bash\nnpm run dev\n```\n\nOpen [http://localhost:3000](http://localhost:3000) with your browser to see the result.\n\n## Deployment\n\nThe project runs smoothly on both Vercel and Netlify. Just ensure to set the environment variables as previously explained. For your convenience, you can deploy the project on Vercel using this button:\n\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fdatocms%2Fnextjs-with-cache-tags-starter\u0026env=PUBLIC_DATOCMS_API_TOKEN,WEBHOOK_TOKEN,TURSO_DATABASE_URL,TURSO_AUTH_TOKEN\u0026envDescription=Please%20fill%20in%20the%20following%20information\u0026envLink=https%3A%2F%2Fgithub.com%2Fdatocms%2Fnextjs-with-cache-tags-starter%3Ftab%3Dreadme-ov-file%23step-2-environment-variables)\n\n**Important:** Once the site is deployed and you know the final domain, you need to set up a [\"Invalidate cache tag\" webhook](https://www.datocms.com/docs/content-delivery-api/cache-tags#step-3-implement-the-invalidate-cache-tag-webhook) on your DatoCMS project, configured like this:\n\n* URL: https://`\u003cYOUR-DOMAIN\u003e`/api/invalidate-cache-tags\n* Custom headers: `Webhook-Token: \u003cYOUR_WEBHOOK_TOKEN\u003e`\n* Trigger:\n  * Entity: Content Delivery API Cache Tags\n  * Events: Invalidate\n\n\u003cimg src=\"https://github.com/datocms/nextjs-with-cache-tags-starter/raw/main/images/webhook.png\" width=\"500\" /\u003e\n\n## Useful resources to navigate the code\n\nThis repository aims to demonstrate how you can selectively invalidate the Next.js cache when receiving DatoCMS Cache Tags invalidation events. Before exploring this repository, it's very useful to understand the general concepts behind Cache Tags:\n\n- DatoCMS Cache Tags: [Announcement](https://www.datocms.com/blog/introducing-datocms-cache-tags), [Documentation](https://www.datocms.com/docs/content-delivery-api/cache-tags)\n- Cache Tags with Next.js: [Guide](https://www.datocms.com/docs/next-js/using-cache-tags)\n\nThe code essentially consists of two parts that are strongly interdependent:\n\n### Execution of GraphQL queries\n\nThe [`executeQuery()` function](https://github.com/datocms/nextjs-with-cache-tags-starter/blob/main/lib/fetch-content.ts#L20) is responsible for executing a GraphQL query using the DatoCMS Content Delivery API and caching the result. To support cache invalidation, the request is tagged with a unique identifier in the Next.js Data Cache.\n\nThe mapping between the unique identifier of the query, and the DatoCMS Cache Tags returned in the response is stored in Turso. We use a [simple table](https://github.com/datocms/nextjs-with-cache-tags-starter/blob/main/schema.sql) made up of just two columns:\n\n* `query_id` (TEXT): A unique identifier for the query, used to tag the request;\n* `cache_tag` (TEXT): The actual cache tag returned by the query.\n\nYou can switch the storage option from Turso to other options by adjusting the code in [`lib/database.ts`](https://github.com/datocms/nextjs-with-cache-tags-starter/blob/main/lib/database.ts).\n\n### \"Cache Tags Invalidation\" webhook\n\nThe [route handler `/api/invalidate-cache-tags`](https://github.com/datocms/nextjs-with-cache-tags-starter/blob/main/app/api/invalidate-cache-tags/route.ts) receives [\"Cache Tag Invalidation\" events from a DatoCMS webhook](https://www.datocms.com/docs/content-delivery-api/cache-tags#step-3-implement-the-invalidate-cache-tag-webhook) and is responsible for invalidating every cached GraphQL query that is linked to those tags.\n\nSince the `executeQuery()`:\n\n- Tags each GraphQL request with a unique ID in the Next.js Data Cache, and\n- Saves the \"Query ID \u003c-\u003e Cache Tags\" mapping on a Turso database...\n\nThe endpoint can find in the database the query IDs associated with the received tags, and use `revalidateTag()` to invalidate the relevant requests.\n\n\u003c!--datocms-autoinclude-footer start--\u003e\n\n---\n\n# What is DatoCMS?\n\n\u003ca href=\"https://www.datocms.com/\"\u003e\u003cimg src=\"https://www.datocms.com/images/full_logo.svg\" height=\"60\" alt=\"DatoCMS - The Headless CMS for the Modern Web\"\u003e\u003c/a\u003e\n\n[DatoCMS](https://www.datocms.com/) is the REST \u0026 GraphQL Headless CMS for the modern web.\n\nTrusted by over 25,000 enterprise businesses, agencies, and individuals across the world, DatoCMS users create online content at scale from a central hub and distribute it via API. We ❤️ our [developers](https://www.datocms.com/team/best-cms-for-developers), [content editors](https://www.datocms.com/team/content-creators) and [marketers](https://www.datocms.com/team/cms-digital-marketing)!\n\n**Why DatoCMS?**\n\n- **API-First Architecture**: Built for both REST and GraphQL, enabling flexible content delivery\n- **Just Enough Features**: We believe in keeping things simple, and giving you [the right feature-set tools](https://www.datocms.com/features) to get the job done\n- **Developer Experience**: First-class TypeScript support with powerful developer tools\n\n**Getting Started:**\n\n- ⚡️ [Create Free Account](https://dashboard.datocms.com/signup) - Get started with DatoCMS in minutes\n- 🔖 [Documentation](https://www.datocms.com/docs) - Comprehensive guides and API references\n- ⚙️ [Community Support](https://community.datocms.com/) - Get help from our team and community\n- 🆕 [Changelog](https://www.datocms.com/product-updates) - Latest features and improvements\n\n**Official Libraries:**\n\n- [**Content Delivery Client**](https://github.com/datocms/cda-client) - TypeScript GraphQL client for content fetching\n- [**REST API Clients**](https://github.com/datocms/js-rest-api-clients) - Node.js/Browser clients for content management\n- [**CLI Tools**](https://github.com/datocms/cli) - Command-line utilities for schema migrations (includes [Contentful](https://github.com/datocms/cli/tree/main/packages/cli-plugin-contentful) and [WordPress](https://github.com/datocms/cli/tree/main/packages/cli-plugin-wordpress) importers)\n\n**Official Framework Integrations**\n\nHelpers to manage SEO, images, video and Structured Text coming from your DatoCMS projects:\n\n- [**React Components**](https://github.com/datocms/react-datocms)\n- [**Vue Components**](https://github.com/datocms/vue-datocms)\n- [**Svelte Components**](https://github.com/datocms/datocms-svelte)\n- [**Astro Components**](https://github.com/datocms/astro-datocms)\n\n**Additional Resources:**\n\n- [**Plugin Examples**](https://github.com/datocms/plugins) - Example plugins we've made that extend the editor/admin dashboard\n- [**Starter Projects**](https://www.datocms.com/marketplace/starters) - Example website implementations for popular frameworks\n- [**All Public Repositories**](https://github.com/orgs/datocms/repositories?q=\u0026type=public\u0026language=\u0026sort=stargazers)\n\n\u003c!--datocms-autoinclude-footer end--\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatocms%2Fnextjs-with-cache-tags-starter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdatocms%2Fnextjs-with-cache-tags-starter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatocms%2Fnextjs-with-cache-tags-starter/lists"}