Articles
The SEO app writes pages into your repository as files, and your own site builds them — what it does, what it does not, and how the wiring goes.
You have a site. You want pages on it that a search engine finds and a person
reads to the end. The SEO app is where those pages are written, and where they
are written to is your repository.
What it does, and where it stops
An article is a file: .beafk/seo/<collection>/<slug>.mdx, in the project the
panel is standing in. A collection is a folder in there — blog, changelog,
compare — and it is committed with the rest of your work, reviewed the way
your code is reviewed, and deployed by whatever already deploys your site.
beafk serves nothing. There is no CDN of ours and nothing of ours runs when
a reader arrives. beafk writes the file; your build turns it into a page; your
host puts it on the web. If your site deploys from a push, nothing is on the
web until somebody pushes.
beafk writes nothing either. No model of ours runs on your articles. The
agent on your machine — Claude Code, Codex, Grok Build, Kimi Code, on the
subscription you already pay for — is the writer, and the app is where you ask
it and where you read what it wrote.
The file
Five lines of front matter, then the page:
---
title: Nothing is deleted — a thirty day drawer instead
description: One sentence, under 160 characters, that a result will show.
tags: [trash, design]
cover: /covers/piece-a1b2c3.png
coverAlt: the trash screen, thirty days of it
---
The editor draws its fields from those five and nothing else. The
description is what a search result shows and it is cut at 160 characters;
the editor draws a line there. The cover is the URL a reader's browser will
fetch — never a path relative to the file, because that previews perfectly and
ships a broken image.
The body is markdown, and it may use your site's own components as tags —
<Callout>, <Figure> — without importing them. Your site supplies them by
name when it renders. Keep the body to markdown and tags: an export or a
{rows.map(…)} compiles on Astro and Next and prints as text on Hugo,
Eleventy and SvelteKit.
Making your site read it
Your framework has to be pointed at the folder once, per collection. Every
framework can be: Astro's glob loader takes a base, Hugo takes a module
mount, Nuxt Content takes a cwd, Next reads the folder with
next-mdx-remote, Eleventy takes a symlink or a virtual template. That is a
job for the agent, and the page it reads first is the setup-articles
skill — it is on every machine, and it is what an agent given "the site does
not show my articles" opens before touching a config file.
Two things it will need from you:
- The site's public address.
og:image and the canonical link have to be
absolute, and a build that does not know its own origin ships
http://localhost:3000 in the head of every page. It is site in Astro,
metadataBase in Next, baseURL in Hugo. Have it in the config, or say it.
- Where the pictures go. A cover's bytes must be somewhere the site
serves. Either the folder your build already serves —
public/, static/ —
or a bucket you own (S3, R2, Backblaze, MinIO), where the object is public
and the URL is permanent. A covers/ folder beside the articles is not
served by anything until it is copied or mounted.
Then the check that matters is not the build's exit code. It is the built HTML
of one article: the six head tags, the cover the head names present in the
output, and no component printed as text.
What "published" means
A draft is a file whose name starts with _. Every loader the skill sets up
skips it, so a draft stays in the folder, in the repository, and off the site.
Publishing is the person's press, not the agent's. An agent asked to write a
page writes the file and says it is ready; committing it and pushing it are
yours, and so is renaming a slug — a slug is a live URL, and a rename without a
redirect is a page that was indexed and is now a 404.
What it cannot do yet
As of September 2026 the app reads and writes your repository through the
machine: the library lists the collections and articles that are really in
.beafk/seo, the editor saves the file (and refuses to write over a version an
agent changed under it), and the publish switch renames a draft and makes one
scoped commit of that one file. Two things are still yours to do by hand:
- Bucket credentials are not stored. The storage screen keeps the bucket's
endpoint, name and prefix, and the folder the site serves pictures from, but
no key. Put a cover's bytes where the site serves them, or upload them with
your own tooling, and write the URL into the front matter.
- Nothing pushes. A publish is a commit in your repository; the push, and
the build that follows it, are your pipeline's.
The two skills, write-an-article and setup-articles, were tested on
Astro, Next, Hugo, Eleventy, SvelteKit and Nuxt with four different agents.