Frontend Setup
The Next.js frontend consumes Directus via GraphQL. Get it running locally in under 5 minutes.
Prerequisites
- Node.js 20+ (npm is fine: the frontend uses plain npm, no pnpm).
- A running Directus instance. See Directus CMS Setup for the zero-command path.
Install
cd frontend
npm install
Environment variables
Create frontend/.env.local:
NEXT_PUBLIC_DIRECTUS_URL=http://localhost:8055
NEXT_PUBLIC_SITE_URL=http://localhost:3000
NEXT_PUBLIC_DEFAULT_LOCALE=en
No token required. The Directus Public role has read access on every content collection, granted automatically by the bootstrap script. Build-time and runtime fetches are unauthenticated GraphQL queries.
Optional variables:
| Var | Purpose |
|---|---|
RESEND_API_KEY | Enables the contact-form email delivery path. |
NEXT_PUBLIC_GA_ID | Google Analytics |
NEXT_PUBLIC_GTM_ID | Google Tag Manager |
NEXT_PUBLIC_BOOKING_URL | Calendly / Cal.com link shown in the floating booking CTA. |
Run
npm run dev
Open http://localhost:3000. Default locale is English at / (also accessible at /en). Other locales live at /fr and /es.
How the GraphQL client works
The frontend talks to Directus via POST /graphql: no REST, no SDK, just typed fetch() calls against the schema Directus exposes.
All fetchers live in frontend/src/lib/directus.ts:
// Example: services with EN translations
export async function getServices(locale: string): Promise<Service[]> {
const data = await gql<{ services: Service[] }>(
`query ($locale: String!) {
services(sort: ["sort"]) {
id slug icon sort seo
translations(filter: { languages_code: { code: { _eq: $locale } } }) {
languages_code { code }
title description features
}
}
}`,
{ locale }
);
return flattenList(data?.services);
}
Responses are flattened so the rest of the app sees languages_code: "en" instead of the GraphQL-shaped { code: "en" }.
Next.js fetch caching is on by default with a 60-second revalidation: CMS edits appear without a rebuild.
Type-check and build
npm run lint
npm run build
Both must pass with zero errors before deploying.
Next steps
- Content Management: edit the content the frontend consumes.
- Hosting & Deployment: production deploy.