SEO for SaaS
Start
AI snippets

AI snippet for any other stack

SvelteKit, Nuxt, Remix, Express, Rails, Django: the same steps in the project's idiom.

Any other stackSvelteKit, Nuxt, Remix, Express, Rails, Django: the same integration, in the project's own idiom.any@4 · api v1 · tested: API calls in TypeScript and Python, against a mock API. Framework steps not run end to end
Or open inClaude CodeCursorLovableReplit
# Add the SEO for SaaS blog to this site

Articles are written and published by SEO for SaaS and read from its content API. This site renders them. Work out the stack first, then do the steps below in its idiom.

## Done when
- `/blog` lists the published articles; `/blog/<slug>` renders the title as the h1 and every block type.
- Each article page has title, description, canonical, Open Graph and one JSON-LD script.
- The sitemap lists every article with its `<lastmod>`, from the sitemap endpoint.
- The site updates when an article is published, changed, or unpublished: a verified webhook endpoint, or the host's deploy hook for a static site.

## Before changing anything
1. Identify the framework, its version and how it renders (server, static build, or browser only). If it renders only in the browser, STOP: the content key would be exposed and search engines would see an empty page. Tell the user to add server or build-time rendering first.
2. If a `/blog` route exists, STOP and ask whether to replace it, use another path, or cancel.

## The API
- `GET https://api.seoforsaas.dev/api/v1/projects/YOUR_PROJECT_ID/content?page=N&limit=100` → `{ data: Article[], pagination: { hasNext } }`, newest first.
- `GET https://api.seoforsaas.dev/api/v1/projects/YOUR_PROJECT_ID/content/by-slug/{slug}` → `{ data: Article & { related } }`, or 404.
- `GET https://api.seoforsaas.dev/api/v1/projects/YOUR_PROJECT_ID/content/sitemap` → `{ data: { url, lastModified }[] }`, one entry per article, ready for the sitemap.
- Header `Authorization: Bearer $SEOFORSAAS_CONTENT_KEY`. Ask the user for the key (Delivery → Content API keys → Create key); keep it in an environment variable read on the server only.
- Fields and every block type: https://docs.seoforsaas.dev/api/article.md and https://docs.seoforsaas.dev/api/blocks.md. Examples in cURL, TypeScript and Python: https://docs.seoforsaas.dev/api/list.md, https://docs.seoforsaas.dev/api/get.md, https://docs.seoforsaas.dev/api/sitemap.md.
- A real article with every block type, no key needed: https://api.seoforsaas.dev/public/v1/fixtures/article.

## Steps
1. **Data.** In TypeScript or JavaScript, download the client and use `createClient`, `listAllArticles`, `getArticle` and `getSitemap`:
   `curl -fsSL --create-dirs -o src/lib/seoforsaas/types.ts https://seoforsaas.dev/r/files/lib/seoforsaas/types.ts` and the same for `client.ts`. In another language, make the HTTP calls above.
2. **Rendering.** With React available, download the SEO for SaaS components (`https://seoforsaas.dev/r/files/components/seoforsaas/…`: `article.tsx`, `blocks.tsx`, `rich-text.tsx`, `video.tsx`, `json-ld.tsx`, `article.css`) and render `<Article blocks={article.blocks} />`. Otherwise write one component per block type from the block reference, keep the `sfs-*` class names, and copy `article.css`.
3. **Head tags.** From `article.seo`: title, meta description, canonical from `canonicalPath` resolved against the site origin, `og:` tags, and `jsonLd` in one `<script type="application/ld+json">` with `<` escaped as `\u003c`. Serve article URLs without a trailing slash.
4. **Sitemap.** Add the sitemap endpoint's entries to the site's sitemap as they are (`url` → `<loc>`, `lastModified` → `<lastmod>`); never stamp articles with the build date.
5. **Updates.** Server-rendered with a cache: an endpoint that verifies the Standard Webhooks signature against the RAW body (`standardwebhooks` package, secret from Delivery → Webhook → Signing secret → Reveal), returns 401 when it fails, and purges the cache on `content.created` and `content.updated`. Static: no endpoint; the user pastes the host's deploy hook into Delivery → Webhook.

## Rules
- The content key and signing secret never reach browser code or source files.
- Rich text is text runs: never raw-HTML APIs (`dangerouslySetInnerHTML`, `v-html`, `{@html}`, `set:html`, `raw`) for article content.
- Links: only `http(s)`, site paths and `#` anchors; keep each run's `rel`. An unknown block type renders nothing.
- `seo.jsonLd` as it is; never hand-written article JSON-LD.

## Check your work
1. The project's type check, lint and build pass.
2. `/blog` and an article return 200; an unknown slug returns 404.
3. The example article renders every block type through your renderer.
4. An article page has each head tag once; a POST without a signature to the webhook endpoint returns 401.
5. The sitemap lists every article URL with a `<lastmod>`, on the site's own origin. If the origin differs, tell the user: the entries are built on the website URL in the dashboard (Settings → Site and URLs).

## Report back
Files changed; what the user must do (secrets, deploy, the webhook URL or deploy hook in Delivery → Webhook, then Send test event); anything skipped and why.