# Astro metadata

> **Section:** [Guides](https://docs.atmyapp.com/guides.md)
> **Related:** [AtMyApp with Astro](https://docs.atmyapp.com/guides/astro.md) · [Astro forms](https://docs.atmyapp.com/guides/astro-forms.md) · [Astro modes and previews](https://docs.atmyapp.com/guides/astro-previews.md) · [CLI Guide](https://docs.atmyapp.com/guides/cli.md) · [Integration diagnostics](https://docs.atmyapp.com/guides/diagnostics.md) · [Forms on any JavaScript website](https://docs.atmyapp.com/guides/forms.md) · [Define your content schema](https://docs.atmyapp.com/guides/structure.md)
> **Also:** [HTML version](https://docs.atmyapp.com/guides/astro-metadata) · [Docs index](https://docs.atmyapp.com/llms.txt)

---
## Website settings

Open **Settings → Website settings** in AtMyApp. Configure your website name, default page title and description, one website icon, and a sharing image. The editor shows live browser-tab and shared-link previews. Changes save as drafts; use Preview and Review & publish to apply them.

The settings are framework-independent. Astro only supplies the page URL and renders the resolved tags.

```astro
---
import AtMyAppHead from '@atmyapp/astro/components';
---
<head>
  <AtMyAppHead />
</head>
```

## Page titles and overrides

With website name `Altana` and **Add website name to page titles** enabled:

```astro
<!-- Uses the default website title exactly as entered -->
<AtMyAppHead />

<!-- Menu · Altana -->
<AtMyAppHead title="Menu" />

<!-- Uses this exact title -->
<AtMyAppHead title="Altana — Italian kitchen & garden" titleMode="absolute" />
```

Each field resolves independently: **page props → website settings → local `defaults`**. Missing values, empty strings, and empty objects inherit. `null` explicitly clears a field, including its derived social fallback. The two dashboard switches have explicit defaults; they take precedence over local defaults.

```astro
<AtMyAppHead
  title={article.title}
  description={article.summary}
  image={article.coverUrl}
  defaults={{ title: 'My website', description: 'A local fallback' }}
/>
```

Shared-link text inherits the resolved title and description unless **Use different text for shared links** is enabled. Explicit page `ogTitle`, `ogDescription`, or `ogImage` override corresponding website defaults. `image` supplies the sharing image when there is no `ogImage` override. An explicit `titleTemplate` remains available in code; `titleMode="absolute"` bypasses all title formatting.

## One website icon

Choose and crop one square image in Website settings. AMA generates PNG variants at 32, 180, 192 and 512 pixels plus a web manifest on the server. The settings, icon, and variants are published together; conversion failure prevents publication and leaves the previous version intact. Unchanged icons reuse existing variants.

The SDK receives URLs and renders links. It has no image-processing dependency or icon build step. This works for static and server-rendered pages. Draft previews use the selected source image before publication.

Icons supplied directly in code, such as `defaults={{ icon: '/icon.png' }}`, remain developer-managed. Use explicit `favicon`, `appleTouchIcon`, and `manifest` props if you provide your own variants. Set Astro's production `site` to resolve relative URLs.

## Canonical and structured metadata

Configure the production `site` in `astro.config.mjs`. Canonical URLs use that origin and each page's path, excluding request query strings and fragments. Explicit canonical URLs also have `amaPreviewKey` removed. Use `canonical={null}` to omit the tag. Preview pages always emit `noindex, nofollow`.

The production homepage receives basic `WebSite` JSON-LD from the website name and production URL. Other pages receive no automatically inferred structured data in this version. Explicit `jsonLd` replaces that object; `jsonLd={null}` disables it. Values are escaped for safe script serialization.

```astro
<AtMyAppHead
  title="Contact"
  jsonLd={{ '@context': 'https://schema.org', '@type': 'Organization', name: 'Example' }}
/>
```

AI enrichment after publication is a separate upcoming hosting feature. It is not enabled by these settings yet.

## Other frameworks and direct reads

The shared contract and resolver are exported from `@atmyapp/structure` and re-exported by `@atmyapp/core`:

```ts
import { resolveWebsiteMetadata, type Metadata } from "@atmyapp/core";
const { config } = await client.systemConfig.get<Metadata>({
  systemKey: "website.metadata",
});
const metadata = resolveWebsiteMetadata(
  { title: "Menu" },
  config,
  {},
  new URL("https://example.com/menu"),
  new URL("https://example.com/")
);
```

The experimental Astro-specific configuration has been replaced by `_SystemConfig/website/metadata.json` and `GET /system-config/website.metadata`. Update the SDK and backend together, and initialize Website settings. No old-path migration or compatibility alias is provided.

## Metadata availability

By default, missing or unavailable metadata raises a clear error. For a website that intentionally tolerates unavailable managed metadata, use `metadataError="fallback"` and local `defaults`. Preview errors still fail so an editor is not shown misleading published defaults.

```astro
<AtMyAppHead metadataError="fallback" defaults={{ title: 'Example' }} />
```

## Analytics

`<AtMyAppHead trackPageView />` enables page-view events. They are disabled on preview pages. For custom browser events, import `getClient` from `@atmyapp/astro/client`. The head component supplies public configuration. It does not load arbitrary external analytics scripts from metadata fields.

## Sitemap and robots

The `sitemap` field only emits a discovery link. Use the official integration to generate the file:

```sh
npm install @astrojs/sitemap
```

```js
import sitemap from "@astrojs/sitemap";
// Add alongside atmyapp() in astro.config.mjs:
// integrations: [atmyapp(), sitemap()]
```

Set `site` in Astro config and set metadata `sitemap` to `/sitemap-index.xml`. Generated static collection routes participate automatically. Dynamic server-only routes need explicit URL enumeration; consult [Astro sitemap configuration](https://docs.astro.build/en/guides/integrations-guide/sitemap/).

For a static site, add `public/robots.txt`:

```text
User-agent: *
Allow: /
Sitemap: https://www.example.com/sitemap-index.xml
```

Use your actual production domain. Preview noindex is emitted by the head component; a public robots.txt file is shared unchanged between modes. Robots directives are not access control.