Astro’s default zero-JavaScript static and hybrid rendering architecture is perfect for building high-performance brand websites and blogs. With the Kanorio Content Delivery API, you can fetch all your published collections and articles directly at the top of your .astro components using just a few lines of code.
Add your Kanorio site's permanent system URL to your Astro project's .env file:
PUBLIC_KANORIO_SITE_URL="https://s-k4m9x2p7q8w3.kanorio.com"
src/pages/projects.astro)Call /api/v1/collections/{key}/items directly in the Frontmatter block of your .astro file and retrieve image URLs using the top-level assets map:
--- const SITE_URL = import.meta.env.PUBLIC_KANORIO_SITE_URL; const res = await fetch(`${SITE_URL}/api/v1/collections/projects/items?sort=-publishedAt&limit=20`); const { items, assets } = await res.json(); --- <section> <h1>Projects</h1> <div class="grid"> {items.map((item) => { const cover = assets[item.fieldData.cover]; return ( <article> {cover && ( <img src={cover.url} alt={cover.alt ?? item.fieldData.title} width={cover.width ?? undefined} height={cover.height ?? undefined} loading="lazy" /> )} <h2>{item.fieldData.title}</h2> <p>{item.fieldData.summary}</p> </article> ); })} </div> </section>
src/pages/blog/[slug].astro)When fetching the blog collection, include formats=html and expand=authors,categories. You can then pass item.contentHtml directly to Astro's set:html for rendering and use item.toc to generate a table of contents:
--- const SITE_URL = import.meta.env.PUBLIC_KANORIO_SITE_URL; export async function getStaticPaths() { const siteUrl = import.meta.env.PUBLIC_KANORIO_SITE_URL; const res = await fetch(`${siteUrl}/api/v1/collections/blog/items?fields=title&limit=100`); const { items } = await res.json(); return items.map((post) => ({ params: { slug: post.slug } })); } const { slug } = Astro.params; const res = await fetch( `${SITE_URL}/api/v1/collections/blog/items/${encodeURIComponent(slug!)}?expand=authors,categories,tags&formats=html` ); if (!res.ok) return Astro.redirect("/404"); const { item, assets } = await res.json(); const coverId = (item.fieldData.cover_image ?? "").replace(/^asset:/, ""); const cover = assets[coverId]; --- <article> <h1>{item.fieldData.title}</h1> {cover && <img src={cover.url} alt={cover.alt ?? item.fieldData.title} />} {item.toc?.length > 0 && ( <nav aria-label="Table of Contents"> <ul> {item.toc.map((h) => ( <li data-level={h.level}> <a href={`#${h.id}`}>{h.label}</a> </li> ))} </ul> </nav> )} <div class="prose" set:html={item.contentHtml} /> </article>
GET ${PUBLIC_KANORIO_SITE_URL}/api/v1/forms/{formId}/challenge from the browser, and then POST to /api/v1/forms/{formId}/submit upon submission (see full steps in Integrating Online Forms in Headless Frontends). Remember to add your production domain to the "Allowed Origins" list in "Site Settings › Developer" in the dashboard.@astrojs/cloudflare or @astrojs/node): You can pass through or compare the x-kanorio-public-version and X-Kanorio-Cache-Tags headers.collections.item.published, collections.item.unpublished, collections.item.deleted, and collections.items.bulkChanged to trigger automatic redeployments whenever content is published or updated.No. During the build phase (getStaticPaths and .astro server blocks), requests are made in a Node.js environment and bypass browser same-origin checks. You only need to add your frontend domain to "Allowed Origins" if you are making cross-origin API calls from the visitor's browser using <script> (e.g., submitting contact forms or real-time search).