Skip to content

Rendering Pages

The CMS stores pages and blocks (Pages and Blocks); your Astro site renders them. @kenresoft-cms/astro is framework-agnostic and has no Astro components. It provides the data and route resolution. The reference block components live in the CMS repository’s examples/astro-site/src/components/blocks/, which you copy and adapt.

import { createKenresoftClient, resolveSiteRoute } from '@kenresoft-cms/astro';
const [pages, patterns] = await Promise.all([cms.pages.list(), cms.routePatterns.list()]);
const result = resolveSiteRoute(Astro.url.pathname, pages, patterns);
// { kind: 'page', route } | { kind: 'entry', contentTypeSlug, slug } | { kind: 'notFound' }

resolveSiteRoute checks a page’s exact route first, then falls back to content-type route patterns such as /blog/{slug}. resolveRoute(pathname, patterns) does the content-type half alone.

For a page result, fetch the full page and render it:

const page = await cms.pages.resolve({ route: result.route }); // Page | null

The example site does this in a src/pages/[...route].astro catch-all. Astro always prefers your static, named routes over a rest-parameter catch-all, so a page created at a route that matches an existing static file is unreachable. The example does not render generic entry matches, since it has purpose-built templates.

Block types are hero, richText, image, cta, columns, spacer, reusableBlockRef and rawHtml. In the example, BlockRenderer.astro resolves a component with resolveBlockRenderer(type) ?? builtIn[type], so an override registered with registerBlockRenderer(type, component) always wins regardless of import order. A reusableBlockRef block is fetched live with cms.reusableBlocks.get({ id }). A dangling reference or an unknown block type renders nothing rather than failing the page.

Render rawHtml only from the public API’s output, which is sanitized on every read, and consider a Content-Security-Policy.

import { resolveNavigationItems } from '@kenresoft-cms/astro';
const items = resolveNavigationItems((await cms.settings.navigation()).items ?? [], pages);
// { label, href, visible, order, external, newTab }[] (href is null if a linked page was deleted)

Pages support Live Preview. Check for a preview token before resolving against the published-only pages.list().