Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions content/(dynamic)/content-sync.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
title: Content source metadata
description: Set the title, publication date, slug, and status of a source-backed WordPress document.
---

When Content management is enabled for your team, Markdown and HTML files bound to WordPress documents can carry their own metadata. Use the document header below to preserve titles and publication dates during a migration.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Bug · Public page documents an internal-only, default-off feature under a name that doesn't exist

The header is only processed for teams with the content.managed feature. The monorepo feature registry (packages/common/src/contracts/feature-lifecycle.ts) lists it as "Managed content", stage internal, default off, with its docs channel set to the handbook (/features/content). The control plane gates content releases on evaluateFeature("content.managed").

Public readers get a nav entry and two inline links to a feature they can't enable, and the page calls it "Content management", a name no UI or setting uses. This repo documents only shipped, publicly verifiable behavior (AGENTS.md).

Hold the page and cross-links until the feature is public, or move the content to the handbook. If it ships now, use the name "Managed content" and say how a team gets it enabled.

Found by Indent Review Agent

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed against the feature registry. Closed this public-docs PR and moved the guide to the private handbook in https://github.com/spacefast/contextslop/pull/6, with the content.managed enablement prerequisite. Handbook typecheck, 53 tests, and build pass.

View session


## Document metadata

Put a single-line JSON object inside a `spacefast:document` HTML comment at the very start of the file, before its body. Do not put a blank line or other text before the comment.

```markdown content/posts/first-post.md
<!-- spacefast:document {"version":1,"title":"My first post","slug":"first-post","status":"publish","dateGmt":"2026-01-15T09:30:00Z"} -->

The post body starts here.
```

The same header works before an HTML document body. It stores WordPress fields separately from the editable content; it is not a visible heading or a page layout.

| Field | Required | Meaning |
| --- | --- | --- |
| `version` | Yes | Must be `1`. |
| `title` | Yes | The WordPress document title, up to 2,000 UTF-8 bytes. |
| `slug` | Yes | The WordPress document slug, up to 200 UTF-8 bytes. |
| `status` | Yes | `draft`, `pending`, `publish`, `private`, `future`, or `trash`. |
| `dateGmt` | No | Publication time in UTC, such as `2026-01-15T09:30:00Z`. Required when `status` is `future`. |
| `componentSource` | No | The original component path recorded by a source conversion. Preserve it when it is already present. |

`dateGmt` must end in `Z`. Fractional seconds are accepted but stored to whole seconds. Do not add other keys to the JSON object.

## Editing and migration

WordPress editor saves write the metadata header back to the source file alongside the body. Preserve that header when you edit the file locally. Its JSON keys may be reordered when the source is saved.

Without this header, the source does not set the document's metadata. A new document gets a title derived from its filename or binding slug. Existing WordPress metadata is retained during source adoption.

YAML front matter is not read as document metadata. A `title:` or `date:` field between `---` lines does not set the WordPress title or publication date. Replace that front matter with the JSON header before publishing source-backed documents. Otherwise a migrated post's original date is not supplied to WordPress, which can change date-based query ordering.
2 changes: 1 addition & 1 deletion content/(dynamic)/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ export default defineMeta({
title: "Dynamic",
collapsed: false,
order: 5,
pages: ["zero-runtime", "functions", "database", "environment-variables", "crons", "object-storage", "logs", "wordpress"],
pages: ["zero-runtime", "content-sync", "functions", "database", "environment-variables", "crons", "object-storage", "logs", "wordpress"],
});
2 changes: 2 additions & 0 deletions content/(dynamic)/wordpress.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Every Space includes a WordPress install behind its published files. Reach it th

Your published files serve in front of WordPress, so a static Space never touches it and never pays for it. It is there because it is what makes a Space more than a bucket: [Zero](/zero-runtime) apps run on it, [Storage](/object-storage) is its media library, and [Database](/database) is its MySQL. This page covers the two ways to reach that WordPress directly.

For source-backed WordPress documents, see [content source metadata](/content-sync) to set titles, publication dates, and status from Markdown or HTML.

## `sf wp`

`sf wp` is the escape hatch under every named surface: whatever WP-CLI can do that Spacefast has not given its own command.
Expand Down
4 changes: 4 additions & 0 deletions content/(dynamic)/zero-runtime.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,10 @@ export default capsule({

Call them from the client with `useAction("invite")`. `scope: "/"` covers the whole space; `/docs` covers one subtree. Both routes return the Person in `{ data }`. The invite link itself only ever travels by email.

## Document metadata

For Markdown or HTML files bound to WordPress documents, set titles and publication dates with [content source metadata](/content-sync). YAML front matter does not set those fields.

## Styling

Write Tailwind classes in your JSX. Zero compiles them at publish, so do not add a CSS, PostCSS, or Tailwind pipeline. `@plugin` and `@config` directives are rejected, and `theme.json` plus utility classes are the whole styling story.
Expand Down
1 change: 1 addition & 0 deletions scripts/verify-routes.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ const representativePages = [
["errors/rate_limited/index.html", `${docsRoot}/errors/rate_limited`, "rate_limited"],
["recipes/vite/index.html", `${docsRoot}/recipes/vite`, "Vite"],
["zero-runtime/index.html", `${docsRoot}/zero-runtime`, "What Zero is"],
["content-sync/index.html", `${docsRoot}/content-sync`, "Document metadata"],
];
for (const page of representativePages) {
await requirePage(...page);
Expand Down
Loading