> ## Documentation Index
> Fetch the complete documentation index at: /docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Astro

> Use Fimo content, labels, and native components in Astro pages.

Astro pages read Fimo content on the server and render it through native `.astro` components. Fimo adds Studio preview, editing, and the site-wide SEO defaults from Studio's SEO settings without installing React or taking control of Astro routing or per-page metadata.

Start a new Astro project with the opt-in first-party shell:

> [tab] npm
>
> ```bash theme={null}
> npx fimo@latest init my-astro-site --framework astro --package-manager npm
> ```

> [tab] Bun
>
> ```bash theme={null}
> bunx fimo@latest init my-astro-site --framework astro --package-manager bun
> ```

> [tab] pnpm
>
> ```bash theme={null}
> pnpm dlx fimo@latest init my-astro-site --framework astro --package-manager pnpm
> ```

> [tab] Yarn
>
> ```bash theme={null}
> yarn dlx fimo@latest init my-astro-site --framework astro --package-manager yarn
> ```

Next.js App Router is the default when `--framework` is omitted.

The starter is barebones: one disposable welcome homepage, no schemas, and a single `home` route. Replace the homepage and declare the content models your site needs.

The Astro starter sets `devToolbar: { enabled: false }` in `astro.config.mjs` so the toolbar cannot cover content during Studio editing. Set `enabled: true` to restore it. Adding Fimo to an existing project leaves its toolbar setting unchanged; you can disable it in that project's config if it interferes with editing.

## Configure the runtime

```json theme={null}
{
  "runtime": { "framework": "astro" }
}
```

Astro owns its static or server output, routes, and 404 behavior. It needs no hosting rewrite.

Install `fimo-astro` at the same version as `fimo`, then add the Fimo integration beside the adapters and integrations the project already uses:

> [tab] npm
>
> ```bash theme={null}
> npm install fimo fimo-astro
> ```

> [tab] Bun
>
> ```bash theme={null}
> bun add fimo fimo-astro
> ```

> [tab] pnpm
>
> ```bash theme={null}
> pnpm add fimo fimo-astro
> ```

> [tab] Yarn
>
> ```bash theme={null}
> yarn add fimo fimo-astro
> ```

```js theme={null}
import { defineConfig } from 'astro/config';
import { fimo } from 'fimo-astro/config';

import fimoConfig from './.fimo/config.json' with { type: 'json' };

export default defineConfig({
  integrations: [fimo()],
  i18n: {
    defaultLocale: fimoConfig.i18n.defaultLocale,
    locales: fimoConfig.i18n.locales,
    routing: { prefixDefaultLocale: false },
  },
});
```

`fimo-astro` owns Fimo hosting for `output: 'server'` projects; content and components stay in `fimo`. Fimo loads its preview script only inside a Fimo preview, reports the current location to Studio, and uses full-page Astro navigation when Studio changes pages. You do not need to add a provider, preview URL, or script tag.

The integration also recovers the hosted preview if Vite re-optimizes a client-island dependency during its first load. You do not need to refresh Studio manually.

A static Astro site hosted elsewhere can import `fimo` from `fimo/astro/config` instead, which wires the preview connector and branch environment without a hosting adapter.

## Generate content clients

Create `src/schemas/<Uid>.json`, then run:

```bash theme={null}
fimo schemas push <Uid>
```

Astro projects receive one server-only `<Uid>.ts` module plus its public types. Fimo does not generate React hooks, `.client.ts` modules, or a client content registry.

## Read and render content

```astro theme={null}
---
import { fimo, getLabels } from 'fimo/astro';
import { Image, RichText, Text } from 'fimo/astro/components';

import * as Article from '../schemas/Article';

const locale = Astro.currentLocale;
const article = await Article.getBySlug(Astro.params.slug ?? '', { locale });
const labels = await getLabels({ locale });
---

<Text as="h1" value={fimo`${labels.t('article.title')}: ${article?.title}`} />
<Image value={article?.cover} />
<RichText value={article?.body} />
```

The native component surface includes `Text`, `RichText`, `Image`, `StaticImage`, `Video`, `Date`, `Boolean`, and `Json`. Pass tracked values directly so Fimo preserves their `data-fimo-source` metadata.

## SEO defaults

Resolve the current route, apply page values, then convert to native attributes.
New projects have this in `src/layouts/Base.astro`. Existing apps should extend
their current head component, preserving unrelated metadata.

```astro theme={null}
---
import { buildSiteSchemas, resolveSeoForPath, serializeJsonLd, toSeoHead } from 'fimo/seo';
import config from '../../.fimo/config.json';

const { seo = resolveSeoForPath(Astro.url.pathname, config) } = Astro.props;
const canonicalUrl = seo?.url ? new URL(Astro.url.pathname, seo.url).href : undefined;
const head = toSeoHead(seo, { canonicalUrl });
const siteSchemas = buildSiteSchemas(seo);
---
<head>
  <title>{head.title ?? 'My site'}</title>
  {head.meta.map((attributes) => <meta {...attributes} />)}
  {head.links.map((attributes) => <link {...attributes} />)}
  {siteSchemas.map((schema) => <script type="application/ld+json" set:html={serializeJsonLd(schema)} />)}
</head>
```

`buildSiteSchemas` returns the site's Organization and WebSite JSON-LD once the
SEO settings have a site name and URL, and nothing before that.

For a content page, resolve after loading the entry and pass the final values
to the layout: `const seo = resolveSeoForPath(Astro.url.pathname, config, { article })`,
then `<Base lang={locale} seo={seo}>`. Route templates can read
`{{article.title}}`. Apply app-owned overrides before conversion so the title,
Open Graph and Twitter tags agree.

The example canonical policy fits a root-hosted site. Preserve the app's own
production domain, base path and trailing-slash policy. Omitting the converter's
`canonicalUrl` omits canonical and `og:url`; `seo.url` alone is only a site base.
A resolved `seo.url` is `FIMO_SITE_URL` when that variable is set, otherwise the
value in `.fimo/config.json`.
Imported config changes need sync and rebuild/redeploy. Content freshness
follows the route's rendering and caching policy.

## Routes and locales

The starter configures Astro's native i18n router from `.fimo/config.json`: the default locale stays unprefixed and other locales use their Astro prefix. Use `Astro.currentLocale` for generated content reads, `getLabels()`, and document language. Existing sites can keep another Astro locale strategy; Fimo does not impose a router or provider.

Client-island content hooks are not part of the Astro surface yet. Preserve existing islands and do not add React just to read Fimo content.

> [card] [Content & CMS](/docs/cli/content.md)
>
> Declare schemas and use generated collection or Single clients.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.