seo
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".
适合你,如果你需要为网站或博客添加SEO元数据与结构化数据
npx oh-my-skill add gridaco/grida/seocurl -fsSL https://oh-my-skill.com/install.sh | bash -s -- gridaco/grida/seonpx oh-my-skill verify gridaco/grida/seo怎么用
技能原文 SKILL.md
SEO
Guidelines for search engine optimization across the Grida project -- Next.js pages, blog posts, and documentation.
Scope
| 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 |
Next.js Pages (editor/app/(www))
Metadata
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:
titleshould end with— Grida(or use atitle.templatein the root layout).descriptionmust be unique per page, under 160 characters, and include primary keywords.- Every page with OG images must set
metadataBaseor use absolute URLs so crawlers resolve them correctly. - OG images must return 200 without auth and use correct
Content-Type.
metadataBase
When 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.
Sitemap
Public pages belong in editor/app/sitemap.ts.
{
url: "https://grida.co/new-page",
changeFrequency: "monthly",
priority: 0.5,
}
- Use
priority: 1only for the homepage. - Match
changeFrequencyto actual update cadence. - When adding a new public page, always add a sitemap entry.
- Sitemaps are split per route group (root,
/packages,/library, …). A newsitemap.tsis invisible to crawlers until it's added as aSitemap:line ineditor/app/robots.txt— non-root sitemaps are not auto-discovered. - Prefer deriving sitemap entries from the page's data source (see
packages/sitemap.ts) over hand-maintained URL lists, which drift.
Google Image Search
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):
- Use
<Image unoptimized>or plain<img>so the renderedsrcis a stable, direct public URL (e.g./brand/grida-symbol-240.png). - Include descriptive
alttext with "Grida" + asset name + format.
Checklist for image assets:
- Returns 200 without cookies; not blocked for
Googlebot-Image - Correct
Content-Type(image/png,image/svg+xml, etc.) - Not blocked by
robots.txtorX-Robots-Tag /_next/imageendpoint itself is not blocked (other pages still use it)- Stable, clean URLs under
public/-- no query-string-only canonicals
Structured Data (JSON-LD)
Use JSON-LD for rich results where applicable:
- Product pages:
ProductorSoftwareApplication - Blog posts:
BlogPostingorArticle - FAQ sections:
FAQPage - Brand/org:
Organization
Embed via a <script type="application/ld+json"> in the page or layout.
Documentation (docs/**)
Docs are built with Docusaurus and published at grida.co/docs.
Frontmatter
Every doc page should have:
--- title: Feature Name description: One-line summary for search snippets (under 160 chars). keywords: [keyword1, keyword2] ---
titlebecomes the<title>tag and H1.descriptionbecomes the meta description.keywordshelp Docusaurus generate meta tags.- Add
slug:only when the default URL path is wrong.
Headings
- Use a single
# H1matching thetitlefrontmatter. - Use
##for sections -- these generate anchor links and appear in the TOC. - Headings should be descriptive and keyword-aware (search engines weight them).
Internal Linking
- Link related docs to each other -- it helps search engines discover pages and improves user navigation.
- Use relative paths within
/docs. - For editor pages, use universal routing:
https://grida.co/_/<path>.
Blog Posts
Title
- Clear, specific, keyword-forward. Front-load the most important words.
- Avoid clickbait or vague titles.
- Good: "How Grida Canvas Renders 10K Nodes at 60 FPS"
- Bad: "Exciting Updates!"
Meta Description
- Write a custom
descriptionin frontmatter (under 160 chars). - Summarize the post's value proposition -- what will the reader learn?
Content Structure
- Open with a clear summary paragraph (search engines often use this as the snippet).
- Use
##headings that include relevant keywords. - Break content into scannable sections.
- Include alt text on all images.
Social Sharing
- Set
image:in frontmatter for the OG image. - OG image should be 1200x630 px for optimal display.
- Ensure the image URL is absolute and publicly accessible.
Crawl Control
robots.txt
Located 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.
Canonical URLs & Tenant Domains
Grida serves grida.co (main) and [tenant].grida.site (tenant sites). Tenant-rendered pages must not compete with grida.co pages in search.
- Public marketing pages under
(www)should set canonical tohttps://grida.co/.... - Tenant pages (
(tenant)) should either setnoindexor canonical to their own*.grida.sitedomain -- never togrida.co. - Preview / embed pages (
(preview)) should benoindex, nofollow.
Known Gaps
- The
(www)root layout (editor/app/(www)/layout.tsx) does not setmetadataBase. Pages with relative OG images should set it themselves (seemetadataBasesection above) or it should be added to the root layout.
General SEO Writing Rules
These apply across all surfaces (pages, docs, blog):
- One primary keyword per page. Include it in the title, first paragraph, and at least one heading.
- Write for humans first. Natural, helpful content ranks better than keyword-stuffed text.
- Unique content. Every page must have a unique title and description. Duplicate meta across pages hurts rankings.
- Descriptive link text. Use meaningful anchor text, not "click here."
- Alt text on images. Describe what the image shows; include keywords when natural.
- URL structure. Keep URLs short, lowercase, hyphenated, and descriptive. Avoid IDs or query params in public URLs.
- Mobile-first. Ensure pages render well on mobile -- Google uses mobile-first indexing.
- Performance. Page speed is a ranking factor. Prefer static/SSG pages for marketing content. Lazy-load below-fold images.
Verification Checklist
Before shipping a public page or post:
- [ ]
titleanddescriptionset in metadata / frontmatter - [ ]
descriptionis under 160 characters and unique - [ ] OG image set, absolute URL, returns 200 without auth
- [ ] Page added to sitemap (Next.js pages)
- [ ] Headings use keywords and follow hierarchy (no skipped levels)
- [ ] All images have
alttext - [ ] No duplicate meta with other pages
- [ ] Page is mobile-friendly
- [ ] Canonical URL is correct (no competing duplicates)