DIRECTUS SEO AUDIT · HEADLESS CMS · REST/GRAPHQL API · NEXT.JS
Free Directus SEO Audit
Directus is a headless CMS — all SEO is implemented in the frontend consuming its REST or GraphQL API. That means generateMetadata() from Directus fields, JSON-LD mapped from collection items, a custom sitemap via Directus API queries, and Core Web Vitals determined by the frontend framework (Next.js, Nuxt, SvelteKit). DeepSEOAnalysis audits the rendered frontend HTML — validating all JSON-LD against Google's Rich Results specs, real CrUX Core Web Vitals, draft content exposure, and all five AI visibility signals — with Directus field paths and frontend component locations for every finding.
WHAT WE CHECK
6 Directus-specific SEO checks
Directus SEO auditing covers custom SEO field configuration and frontend meta tag output, URL routing and slug handling (including draft content exposure), JSON-LD from Directus API fields with property-level validation, API-driven sitemap coverage, real CrUX Core Web Vitals with Directus Files CDN image optimisation, and AI visibility — with Directus Data Studio paths and frontend component locations for each finding.
Directus SEO fields and generateMetadata() output
Directus has no built-in SEO fields — they must be defined in the Directus Data Studio and consumed by the frontend. The audit validates what the rendered frontend outputs for each crawled page. The audit checks: meta title presence and quality (missing meta title is flagged; when the frontend falls back to the Directus item title without a dedicated seo_title field, product or article titles are often not optimised for search — the SEO group field should provide a dedicated seo_title override); meta description coverage (Directus has no auto-generated meta description — if the seo_description field is empty, the frontend often outputs no meta description, which Google then generates from the page body; the audit flags all pages missing a meta description); canonical tag accuracy (the canonical should match the page\'s public URL; if the Directus canonical_url field provides an override, the frontend must use it — incorrect canonical configuration from misconfigured field defaults can cause cross-page canonical conflicts); Open Graph tags (og:title, og:description, og:image — the og:image URL from the Directus Files CDN must be an absolute URL, not a relative path, and must return a 2xx response; Directus file IDs resolve via /assets/[id] on the Directus instance URL); noindex consistency (the Directus noindex boolean field should prevent rendering robots meta content="noindex" — and pages where noindex=true should be excluded from the sitemap; the audit checks for mismatches between noindex meta tags and sitemap inclusion).
Directus URL routing and canonical structure
In a Directus-powered Next.js application, URL routing is handled by the frontend framework — Directus stores a slug field that the frontend maps to public URLs. The audit checks: slug field quality (slugs stored in Directus collections determine the canonical URL path for each content item — auto-generated slugs from the content title are often unoptimised, containing stop words, special characters, or inconsistent casing; the audit checks for non-descriptive URL slugs visible in the canonical tag); slug uniqueness (Directus doesn\'t enforce slug uniqueness across a collection by default — duplicate slugs produce duplicate canonical URLs for different content items; the frontend should handle duplicate slugs with a redirect or use Directus\'s unique field constraint); `generateStaticParams()` coverage (Next.js App Router sites using Directus for static generation must fetch all published slugs in `generateStaticParams()` — the audit checks that all pages referenced in the sitemap return 200 responses, identifying any slugs that fail to resolve through the frontend\'s catch-all route); redirect handling for slug changes (when a Directus item\'s slug changes, the previous URL returns 404 unless the frontend implements redirects — Directus doesn\'t manage frontend redirects automatically; a redirects collection in Directus with source/destination fields, consumed by `next.config.js redirects()`, is the recommended pattern); draft content exposure (Directus uses a status field — "published", "draft", "archived" — the frontend must filter items by `filter: { status: { _eq: "published" } }` in API requests, or draft items may be rendered at their slug URL if the filter is omitted from the data fetching logic).
JSON-LD structured data from Directus items
Directus fields provide the data for JSON-LD structured data, but the mapping and output are entirely frontend responsibilities. The audit validates all JSON-LD found in the rendered HTML against Google\'s Rich Results specifications. For `Article` JSON-LD: the audit checks `headline` length (must be under 110 characters — Directus article titles can exceed this if editors don\'t constrain field length), `datePublished` accuracy (`date_created` Directus auto-field maps correctly; verify the frontend formats it as ISO 8601 — Directus returns timestamps as UTC strings), `dateModified` accuracy (`date_updated` Directus auto-field — verify it updates on content edits, not just metadata changes), `author` as a `Person` object with `name` (requires a Directus Many-to-One relation to an authors collection, fetched with `author.*` in the fields request), `image` as an absolute URL from the Directus Files CDN (must return a 2xx response). For `FAQPage` JSON-LD: the audit checks that the `mainEntity` array has at least 2 question-answer pairs, that each `acceptedAnswer.text` is over 20 characters, and that the questions are not duplicated. For `Product` JSON-LD: `offers.price` must be a number (not a string), `offers.priceCurrency` must be a valid ISO 4217 code, and `offers.availability` must be a schema.org URL. All JSON-LD must be in the server-rendered HTML response — Directus-powered sites using client-side data fetching (React useState/useEffect) for JSON-LD injection will fail the rendering check.
Directus API sitemap and crawl configuration
Directus has no built-in sitemap generation — the frontend application must query the Directus API to build `app/sitemap.ts`. The audit checks: sitemap accessibility (the sitemap must be accessible at /sitemap.xml; Next.js `app/sitemap.ts` generates it automatically from the returned array); content coverage (the sitemap should include all published content items from Directus collections — query with `filter: { status: { _eq: "published" } }` and `limit: -1` to retrieve all records; paginate for large collections); `lastmod` accuracy (Directus\'s `date_updated` field provides the last modification timestamp — map it to the sitemap\'s `lastmod` property; content items with null `date_updated` should fall back to `date_created`); draft content exclusion (the sitemap query must use the published status filter — if the filter is omitted, draft and archived items may appear in the sitemap with URLs that return 404 when the frontend excludes them from rendering); robots.txt configuration (the `app/robots.ts` in Next.js should declare the Sitemap: directive pointing to the sitemap URL; the Directus admin at /admin should be disallowed from indexing — `Disallow: /admin`; the Directus API at /items and /assets should also be disallowed if publicly accessible); and image sitemap metadata (for Directus-powered media sites, the sitemap can include `image:` metadata by fetching image fields alongside page fields in the API query and mapping them to the sitemap entry\'s `images` array in Next.js 15\'s extended sitemap format).
Core Web Vitals for Directus-powered sites
Directus-powered sites run on the frontend framework stack — Core Web Vitals depend on the frontend architecture, not on Directus itself. The audit uses real CrUX field data. **LCP** — the most common LCP element is the featured image from Directus\'s Files system. Directus serves files via its own asset endpoint: `[DIRECTUS_URL]/assets/[file-id]?width=1200&format=webp&quality=80`. For Next.js: configure the Directus CDN URL in `next.config.js` `images.remotePatterns` to allow the Next.js `Image` component to optimise Directus-served images. Use `Image priority` on the article or page hero image (mapped from `item.featured_image.id`) — the Next.js Image component adds `fetchpriority="high"` and disables lazy loading for priority images, directly optimising LCP. For non-Next.js frontends consuming Directus: use the `?format=webp&width=[viewport-width]` query parameters on Directus asset URLs to serve appropriately-sized WebP images, and add `fetchpriority="high"` and `loading="eager"` on the LCP image element. **INP** — Directus-powered SPAs that load content client-side on navigation add JavaScript processing time to INP. Next.js App Router (React Server Components) renders content server-side, reducing client-side JavaScript that affects INP. **CLS** — images fetched from the Directus Files API must have explicit `width` and `height` attributes in the frontend component — these values come from the Directus file object\'s `width` and `height` fields (auto-populated by Directus when files are uploaded). Request `featured_image.width` and `featured_image.height` in the Directus API call and pass them to the `Image` or `img` element.
AI visibility for Directus-powered frontends
AI visibility for Directus-powered sites requires configuration at both the Directus data model level (FAQ fields) and the frontend level (llms.txt, robots.ts). For `llms.txt`: Directus has no native llms.txt support. In a Next.js frontend, add `app/llms.txt/route.ts` that generates the file programmatically — optionally querying the Directus API for a curated list of key pages and their descriptions to include in the llms.txt content. Alternatively, add a static `public/llms.txt` file to the Next.js project. For `robots.txt`: in `app/robots.ts`, ensure GPTBot, ClaudeBot, PerplexityBot, and other AI crawler user agents are not disallowed. The Directus admin (`/admin`) should be disallowed, but the public frontend content paths should be allowed. For `FAQPage` JSON-LD: the most scalable implementation is a `faq_items` JSON field in Directus collections (or a Many field with nested question/answer objects), mapped to FAQPage JSON-LD in the frontend server component. Directus Flows can validate that faq_items contain at least 2 question-answer pairs before allowing publish. For question-heading ratio: implement a Directus relationship pattern where H2 headings in the article body can be structured as question-format fields — either via a Rich Text field (editors write question-format H2 headings) or a repeater field where section headings are defined as typed fields (allowing the frontend to render them as H2 elements). The audit checks all five GEO signals in the rendered frontend HTML — the fix paths reference both the Directus Data Studio field configuration and the Next.js frontend component that consumes it.
HOW IT WORKS
Audit your Directus-powered site in 60 seconds
- Enter your frontend URL. Use the public URL of the application consuming your Directus API — not the Directus admin at /admin, not the API endpoint at /items. No Directus access tokens, API keys, or admin credentials needed. Works with any frontend stack: Next.js, Nuxt, SvelteKit, Astro, Remix, Angular, or any other framework reading from the Directus REST or GraphQL API.
- We crawl and analyse. The engine validates all meta tags output by
generateMetadata()from your Directus fields; checks every JSON-LD block against Google's Rich Results specifications with property-level error detail; verifies the API-driven sitemap covers all published items (not drafts); measures CrUX Core Web Vitals from real Chrome field data; and evaluates all five AI visibility signals in the server-rendered HTML. - You get a prioritised report. Directus-specific issues first — missing SEO field groups in the Data Studio, draft content accessible at public URLs, JSON-LD reading null Directus fields, og:image using relative Directus file paths instead of absolute CDN URLs, sitemap including archived items — then general SEO issues, each with the Directus field path or frontend component file location for the fix.
FAQ
Questions about the Directus SEO audit
Does Directus have built-in SEO features?
Directus (directus.io) is a headless CMS — it stores and exposes content via REST and GraphQL APIs but has no built-in rendering layer. SEO is implemented entirely in the frontend application consuming the Directus API. Directus provides the infrastructure for SEO through: (1) **Custom SEO fields in Directus collections** — you define your own field structure in the Directus Data Studio. For each content type (article, product, landing page), create a dedicated SEO group field containing: meta_title (text field), meta_description (textarea), og_title, og_description, og_image (image field pointing to a Directus file), canonical_url (text field, optional override), noindex (boolean toggle), and schema_type (select field — Article, Product, etc.). The Directus admin interface then presents editors with a structured SEO section per content item. (2) **Directus Flows for SEO automation** — Directus\'s built-in workflow automation (Flows) can trigger on content events (create, update, publish) to: auto-populate meta_title from the content title if left empty; validate meta description length; or trigger a webhook to revalidate Next.js ISR cache when content is published. (3) **Directus Files for image SEO** — Directus has a built-in Files management system with a CDN-delivered file server. Images uploaded to Directus are served from the Directus CDN with format transformation query parameters: `/assets/[id]?format=webp&width=1200&quality=80` for automatic WebP conversion and resizing. The frontend Next.js `Image` component can use a custom loader that reads from the Directus Files API.
How do I implement generateMetadata() with Directus in Next.js?
In a Next.js App Router application using Directus as the headless CMS backend, `generateMetadata()` reads from Directus REST or GraphQL fields and returns the Next.js metadata object. REST implementation: fetch the item by slug from the Directus `/items/[collection]` endpoint, then map the Directus fields to Next.js metadata properties. Example pattern: `const item = await directus.request(readItem("articles", slug, { fields: ["title", "seo_title", "seo_description", "og_image.*", "noindex", "canonical_url"] }))`. In `generateMetadata()`: title from `item.seo_title ?? item.title`; description from `item.seo_description`; canonical from `item.canonical_url ?? \`/blog/${slug}\``; OG image from `item.og_image ? \`${process.env.DIRECTUS_URL}/assets/${item.og_image.id}?format=webp&width=1200\` : defaultOgImage`; robots from `item.noindex ? "noindex, nofollow" : "index, follow"`. GraphQL alternative: use Directus\'s GraphQL API (`/graphql`) with a query that includes the seo fields — `query { articles_by_slug(slug: $slug) { seo_title, seo_description, og_image { id }, noindex } }`. Key consideration: Directus relations (like `og_image.*` to fetch the full file object) must be explicitly requested in the fields array — the default Directus API returns only the file ID, not the full object needed for the CDN URL construction.
How do I add JSON-LD structured data to a Directus-powered Next.js site?
JSON-LD structured data in a Directus-powered Next.js site is implemented in the frontend page component, reading data from Directus API fields. For `Article` JSON-LD: create a server component that fetches the article from Directus and outputs a `script type="application/ld+json"` tag via `dangerouslySetInnerHTML`. Map Directus fields: `headline` from `item.title` (or `item.seo_title`); `datePublished` from `item.date_created` (Directus auto-field); `dateModified` from `item.date_updated` (Directus auto-field); `author` from `item.author.*` (requires a Many-to-One relation to a users or authors collection); `image` from the Directus Files CDN URL of `item.featured_image`. The Directus auto-fields `date_created` and `date_updated` are ISO 8601 timestamps — use them directly in `datePublished`/`dateModified`. For `FAQPage` JSON-LD: create a Many field (array of nested objects) in Directus with a `faq_items` field of type JSON or a repeater structure containing `question` and `answer` text fields per item. In the frontend component, map `item.faq_items` to the `mainEntity` array of the FAQPage JSON-LD object. For `Product` JSON-LD: if using Directus for a product catalogue, map `item.price`, `item.currency`, `item.stock_status`, `item.sku`, and `item.images` to the Product schema properties. All JSON-LD must be output in the server-rendered HTML (not in a client-side `useEffect` or `useState`) — use React Server Components for the JSON-LD output component so it appears in the initial HTML response that Googlebot processes.
Is the Directus SEO audit free?
Yes. The complete audit is free with no signup and no email gate. Enter the URL of the frontend application that consumes your Directus API — the audit crawls the rendered HTML that Googlebot would see, not the Directus admin or API directly. No Directus API keys, admin credentials, or access tokens needed. Works with any frontend stack consuming Directus: Next.js, Nuxt, SvelteKit, Astro, Remix, or any other framework. Paid DeepSEOAnalysis plans add saved report history, scheduled monitoring, larger crawls (up to 1,000 pages), and white-label agency reporting.