SEO best practices for the Grida project across Next.js pages, blog posts, and documentation. Covers Next.js metadata API, Open Graph / Twitter cards, sitemaps, image search optimization, structured data (JSON-LD), Docusaurus frontmatter, and content writing for search. Use when creating or editing public-facing pages under editor/app/(www), writing blog posts, authoring docs, or reviewing SEO-related metadata. Trigger phrases: "SEO", "metadata", "sitemap", "open graph", "og image", "meta tags", "search ranking", "structured data", "JSON-LD".
75
92%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Guidelines for search engine optimization across the Grida project -- Next.js pages, blog posts, and documentation.
| Surface | Location | Framework |
|---|---|---|
| Marketing / product pages | editor/app/(www)/ | Next.js 16 |
| Blog | docs/blog/ or apps/docs/blog/ | Docusaurus |
| Documentation | docs/** | Docusaurus |
| Sitemaps | editor/app/sitemap.ts + others | Next.js |
editor/app/(www))Every public page must export metadata (static or dynamic).
// Static
export const metadata: Metadata = {
title: "Page Title — Grida",
description: "Concise, keyword-rich description under 160 chars.",
keywords: ["relevant", "keywords"],
openGraph: {
title: "Page Title — Grida",
description: "Same or tailored OG description.",
images: ["/og/page-name.png"],
},
twitter: {
card: "summary_large_image",
},
};
// Dynamic
export async function generateMetadata({ params }): Promise<Metadata> { ... }Rules:
title should end with — Grida (or use a title.template in the root layout).description must be unique per page, under 160 characters, and include primary keywords.metadataBase or use absolute URLs so crawlers resolve them correctly.Content-Type.metadataBaseWhen openGraph.images uses relative paths, the layout or page must set:
metadataBase: new URL("https://grida.co"),Without this, crawlers may see broken OG URLs.
Public pages belong in editor/app/sitemap.ts.
{
url: "https://grida.co/new-page",
changeFrequency: "monthly",
priority: 0.5,
}priority: 1 only for the homepage.changeFrequency to actual update cadence./packages, /library, …). A
new sitemap.ts is invisible to crawlers until it's added as a Sitemap:
line in editor/app/robots.txt — non-root sitemaps are not auto-discovered.packages/sitemap.ts) over hand-maintained URL lists, which drift.Next.js <Image> renders optimized /_next/image?url=... URLs that Google
Images indexes unreliably.
For pages where images are the search target (brand assets, logos, press kits):
<Image unoptimized> or plain <img> so the rendered src is a
stable, direct public URL (e.g. /brand/grida-symbol-240.png).alt text with "Grida" + asset name + format.Checklist for image assets:
Googlebot-ImageContent-Type (image/png, image/svg+xml, etc.)robots.txt or X-Robots-Tag/_next/image endpoint itself is not blocked (other pages still use it)public/ -- no query-string-only canonicalsUse JSON-LD for rich results where applicable:
Product or SoftwareApplicationBlogPosting or ArticleFAQPageOrganizationEmbed via a <script type="application/ld+json"> in the page or layout.
docs/**)Docs are built with Docusaurus and published at grida.co/docs.
Every doc page should have:
---
title: Feature Name
description: One-line summary for search snippets (under 160 chars).
keywords: [keyword1, keyword2]
---title becomes the <title> tag and H1.description becomes the meta description.keywords help Docusaurus generate meta tags.slug: only when the default URL path is wrong.# H1 matching the title frontmatter.## for sections -- these generate anchor links and appear in the TOC./docs.https://grida.co/_/<path>.description in frontmatter (under 160 chars).## headings that include relevant keywords.image: in frontmatter for the OG image.robots.txtLocated at editor/app/robots.txt. Currently allows everything except
/private/. When adding new route groups that should not be indexed (e.g.
internal tools, preview embeds, auth flows), add a Disallow: rule here.
Grida serves grida.co (main) and [tenant].grida.site (tenant sites).
Tenant-rendered pages must not compete with grida.co pages in search.
(www) should set canonical to
https://grida.co/....(tenant)) should either set noindex or canonical to their
own *.grida.site domain -- never to grida.co.(preview)) should be noindex, nofollow.(www) root layout (editor/app/(www)/layout.tsx) does not set
metadataBase. Pages with relative OG images should set it themselves
(see metadataBase section above) or it should be added to the root layout.These apply across all surfaces (pages, docs, blog):
Before shipping a public page or post:
title and description set in metadata / frontmatterdescription is under 160 characters and uniquealt text2e0d276
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.