Docs
GitHub
Technical reference

QueryLayer Astro template contract

Bind immutable content revisions to code-owned Astro templates safely.

Edit this page on GitHub ↗

#Boundary

QueryLayer manages template identity and compatibility. Astro owns executable presentation code.

  • site_templates stores a site-scoped template_key, positive integer version, compatible content_type, descriptive metadata, and a JSON Schema document for the revision body.
  • content_revisions.template_id binds an immutable content revision to one exact template version.
  • Each Astro site keeps an explicit code registry that maps template_key@version to an imported .astro component.
  • Database values never become component file paths, imports, JavaScript, CSS, or executable markup.

This follows Astro's documented model: layouts are Astro components used as reusable page templates, layouts accept typed props, and partial templates can be nested inside a site-wide layout with slots.

#Astro registry

Every site implements an allowlisted registry similar to:

import EditorialArticleV1 from './EditorialArticleV1.astro';

const templates = {
  'article.editorial@1': EditorialArticleV1,
} as const;

The route asks QueryLayer for a published revision, resolves its exact key and version through this registry, and passes typed content props to the component. An unknown key or version must fail the build or request visibly; it must never silently select an unrelated template.

Template components can nest the shared site layout so common document markup, metadata, navigation, and footer behavior stay centralized. Template-specific layout and content rendering remain inside the template component.

#Route generation

Astro owns file-based routes. QueryLayer provides the route inventory and published content.

  • A fixed page such as / may use src/pages/index.astro and the same registry resolver.
  • In static output mode, a catch-all route such as src/pages/[...slug].astro must implement getStaticPaths() and return all published paths at build time, as required by Astro's dynamic routing documentation.
  • In on-demand rendering mode, the route reads Astro.params and fetches the matching published page at request time; it does not use getStaticPaths().
  • Static route files take precedence over rest-parameter routes, so specialized tools and landing pages can coexist with the generic CMS route.

#Version lifecycle

Template definition rows are immutable except for status:

  1. Register article.editorial@1 with its content schema.
  2. Create revisions against that active version.
  3. Introduce incompatible presentation or body changes as article.editorial@2.
  4. Deprecate version 1 to prevent new revisions from selecting it.
  5. Keep the version 1 Astro component available while any published or rollback-eligible revision still references it.

Rollback changes only published_revision_id. Because the revision retains template_id, its original layout is restored with its original content.

#Permissions and exposure

  • Organization owners and admins register and deprecate templates.
  • Editors and content agents may select an active template when creating a revision but cannot define executable template contracts.
  • Anonymous production readers can see only the template metadata referenced by published content.
  • Authenticated site members can see the full registry for sites they can access.
  • Cross-site template assignment is rejected before a revision is created.

The public published_content view and authenticated get_preview_revision() function return template_key and template_version. Both remain security invoker contracts governed by underlying RLS.

#Backup Generator Guide

The registered templates are:

  • home.editorial@1 for the fixed / route.
  • article.editorial@1 for long-form pages generated through src/pages/[...slug].astro.

Both use the same minimal body contract:

{
  "markdown": "# Find the Right Backup Generator for Your Home\n\n..."
}

The Astro implementations live in src/templates/HomeEditorialV1.astro and src/templates/ArticleEditorialV1.astro. Both nest the shared BaseLayout.astro.

Configured builds of the Backup Generator Guide use the anonymous published_content inventory as their sole CMS route source. The version-controlled article corpus is loaded only when PUBLIC_QUERYLAYER_CONTENT_MODE=offline is explicitly set for local work; it is never merged into a configured production build.