SEO content
Collections are a good store for SEO content that an external engine generates: landing-page copy, meta tags, sitemap entries, redirect rules. Your site reads it back and renders everything. Floggy stores and versions the content; it does no SEO work itself.
What Floggy does not do
Floggy does not crawl your site, score content, generate meta tags, or serve a sitemap or robots.txt for your domain. Your site renders every one of those. A collection is just where the structured input lives, versioned and promotable. The SEO intelligence, whatever generates the content, lives in your own systems.
Generated content lands as a draft
An engine that writes to a collection produces drafts by default. Nothing it generates reaches a crawler until a production label points at it, which is usually what you want: a batch of machine-written meta tags gets a review gate for free.
When the batch is trusted, publish as you write. Pass label: "production" on create (@floggy/cms 0.2.1 or newer) or push with --publish:
floggy collections push seo-meta ./content/seo-meta --publish
Watch the update case. Regenerating metadata for a page that is already published writes a new version but leaves production on the old one, so the old tags keep serving. --publish moves the label onto the new version, which is what makes a regeneration actually take effect.
Reserved-convention collections
These are recipes, not features. Floggy treats every collection the same. Naming one seo-meta gives it no special behavior; the convention is only so your code and your agents agree on where things live.
| Collection | Holds | Consumed by |
|---|---|---|
seo-meta |
per-route title/description/OG fields | generateMetadata |
sitemap-entries |
one entry per URL, with changefreq/priority |
app/sitemap.ts |
redirects |
{ from, to, permanent } rows |
your middleware or config |
Sitemap from entries
The SDK ships sitemapFromEntries to build sitemap XML from a list of entries.
// app/sitemap.ts
import { createClient, sitemapFromEntries } from "@floggy/cms";
const floggy = createClient({
project: "projecta",
key: process.env.FLOGGY_API_KEY,
});
export default async function sitemap() {
const { entries } = await floggy.collections.entries.list("sitemap-entries", {
perPage: 50,
});
return sitemapFromEntries(entries, {
baseUrl: "https://blog.example.com",
path: "slug", // which data field holds the path
});
}
sitemapFromEntries(entries, { baseUrl, path }) returns the sitemap structure (URL list) for your framework's sitemap output. Page through the collection if you have more than one page of entries.
Metadata from entries
Read a seo-meta entry in generateMetadata and shape it into your framework's metadata object.
// app/[slug]/page.tsx
import { createClient } from "@floggy/cms";
const floggy = createClient({
project: "projecta",
key: process.env.FLOGGY_API_KEY,
});
export async function generateMetadata({
params,
}: {
params: Promise<{ slug: string }>;
}) {
const { slug } = await params;
// Default GET serves the production label.
const { entries } = await floggy.collections.entries.list("seo-meta", {
slug,
full: 1,
});
const meta = entries[0]?.data;
if (!meta) return {};
return {
title: meta.title,
description: meta.description,
openGraph: { title: meta.ogTitle ?? meta.title, images: meta.ogImage ? [meta.ogImage] : [] },
alternates: { canonical: meta.canonical },
};
}
Redirects
Store redirect rows in a redirects collection and read them where your framework resolves redirects (middleware, config, an edge function). Floggy holds the rules; your app applies them.
const { entries } = await floggy.collections.entries.list("redirects", { perPage: 50 });
const rules = entries.map((e) => e.data); // { from, to, permanent }
The point
Your domain serves its own sitemap, robots, metadata, and redirects. Collections just let an external engine version and promote the content behind them, with drafts and rollback, while your site stays the single thing that renders to crawlers.
Next
- Schemas - shape a
seo-metaorsitemap-entriescollection. - Versioning and labels - draft and roll back generated SEO content.