This is a Next.js-based CMS Template with Internationalization (i18n) support that is fully integrated with Directus, offering a CMS solution for managing and delivering multilingual content seamlessly. The template leverages modern technologies like the Next.js App Router, Tailwind CSS, Shadcn components, and built-in i18n support, providing a complete and scalable starting point for building multilingual CMS-powered web applications.
Note: This is the i18n-enabled version of the Next.js CMS template. For a single-language version, see the standard Next.js CMS template.
License required: See the cms-i18n README for Directus setup.
- Next.js App Router: Uses the latest Next.js routing architecture for layouts and dynamic routes.
- Internationalization (i18n): Built-in support for multiple languages with locale-based routing, automatic translation fetching from Directus, and language switcher component.
- Full Directus Integration: Directus API integration for fetching and managing relational data with translation support.
- Locale-Aware Content: Automatic content translation based on URL locale prefixes (e.g.,
/en/,/es/) with fallback to default locale. - Tailwind CSS: Fully integrated for rapid UI styling.
- TypeScript: Ensures type safety and reliable code quality.
- Shadcn Components: Pre-built, customizable UI components for modern design systems.
- ESLint & Prettier: Enforces consistent code quality and formatting.
- Dynamic Page Builder: A page builder interface for creating and customizing CMS-driven pages.
- Preview Mode: Built-in draft/live preview for editing unpublished content.
- Optimized Dependency Management: Project is set up with pnpm for faster and more efficient package management.
Directus allows you to work on unpublished content using Draft Mode. This Next.js template is configured to support Directus Draft Mode out of the box, enabling live previews of unpublished or draft content as you make changes.
In Directus 12, the published content version is called published (formerly main), and every versioned item
automatically gets a draft version. Published items are locked in the Studio — edits happen on the draft version and
are promoted to publish. This template handles both: preview URLs with version=published load the live content (no extra API call needed),
while version=draft (or any custom version key) fetches that version from the API.
- The live preview feature works seamlessly on deployed environments.
- To preview content on localhost, deploy your application to a staging environment.
- Important Note: Directus employs Content Security Policies (CSPs) that block live previews on
localhostfor security reasons. For a smooth preview experience, deploy the application to a cloud environment and use the deployment URL for Directus previews.
This template includes built-in internationalization support with locale-based routing, automatic translation fetching
from Directus, and a language switcher component. The i18n schema (languages collection, translation tables, etc.) is
included in the Directus template located in ../directus/template/. Apply it to your Directus instance using the
Directus Template CLI:
npx directus-template-cli@latest apply <path-to-template>To set up this template, ensure you have the following:
- Node.js (22.x or newer)
- npm or pnpm
- Access to a Directus instance (cloud or self-hosted)
For instructions on setting up Directus, choose one of the following:
You can instantly deploy this template using one of the following platforms:
To get started, you need to configure environment variables. Follow these steps:
-
Copy the example environment file:
cp .env.example .env
-
Update the following variables in your
.envfile:NEXT_PUBLIC_DIRECTUS_URL: URL of your Directus instance.DIRECTUS_SERVER_TOKEN: Server-side token for accessing content, preview, and form submissions. Use the token from your Directus admin account (created during first-launch onboarding). With a licensed instance, you can instead use a token from a user assigned only the Content - Live Preview and Forms - Submission policies.DIRECTUS_ADMIN_TOKEN: Admin token for local type generation only. Never used at runtime.NEXT_PUBLIC_SITE_URL: The public URL of your site. This is used for SEO metadata and blog post routing.NEXT_PUBLIC_ENABLE_VISUAL_EDITING: Visual editing is enabled by default. Set tofalseto disable.
The form API limits multipart request size and field count. Add rate limiting or bot protection at your hosting edge before launching a public form.
-
Install dependencies:
pnpm install
(You can also use
npm installif you prefer.)Note for npm users: This project uses pnpm workspaces. If you're using npm instead, you'll need to:
rm -rf node_modules pnpm-lock.yaml npm install
npm doesn't support pnpm's
workspace:protocol, so you must removepnpm-lock.yamlbefore runningnpm install. The project will generate apackage-lock.jsoninstead. -
Start the development server:
pnpm run dev
-
Visit http://localhost:3000.
This repository includes a utility to generate TypeScript types for your Directus schema.
- Ensure your
.envfile is configured as described above. - Run the following command:
pnpm run generate:types
src/
├── app/ # Next.js App Router and APIs
│ ├── blog/ # Blog-related routes
│ │ ├── [slug]/ # Dynamic blog post route
│ │ │ └── page.tsx
│ ├── [permalink]/ # Dynamic page route
│ │ └── page.tsx
│ ├── api/ # API routes for draft/live preview and search
│ │ ├── draft/ # Routes for draft previews
│ │ │ └── route.ts
│ │ ├── search/ # Routes for search functionality
│ │ │ └── route.ts
│ ├── layout.tsx # Shared layout for all routes
├── components/ # Reusable components
│ ├── blocks/ # CMS blocks (Hero, Gallery, etc.)
│ │ └── ...
│ ├── forms/ # Form components
│ │ ├── DynamicForm.tsx # Renders dynamic forms with validation
│ │ ├── FormBuilder.tsx # Manages form lifecycles and submission
│ │ ├── FormField.tsx # Renders individual form fields dynamically
│ │ └── fields/ # Form fields components
│ │ └── ...
│ ├── layout/ # Layout components
│ │ ├── Footer.tsx
│ │ ├── NavigationBar.tsx
│ │ └── PageBuilder.tsx # Assembles blocks into pages
│ ├── shared/ # Shared utilities
│ │ └── DirectusImage.tsx # Renders images from Directus
│ ├── ui/ # Shadcn and other base UI components
│ │ └── ...
├── lib/ # Utility and global logic
│ ├── directus/ # Directus utilities
│ │ ├── directus.ts # Directus client setup
│ │ ├── fetchers.ts # API fetchers with i18n support
│ │ ├── forms.ts # Directus form handling
│ │ ├── generateDirectusTypes.ts # Generates Directus types
│ │ └── directus-utils.ts # General Directus helpers
│ ├── i18n/ # i18n configuration and utilities
│ │ ├── config.ts # Locale configuration
│ │ ├── utils.ts # Locale path utilities
│ │ └── server.ts # Server-side i18n utilities
│ ├── zodSchemaBuilder.ts # Zod validation schemas
├── middleware.ts # Next.js middleware for locale detection
├── styles/ # Global styles
│ └── ...
├── types/ # TypeScript types
│ └── directus-schema.ts # Directus-generated types