@astrojs/starlight
Version:
Build beautiful, high-performance documentation websites with Astro
70 lines (68 loc) • 2.64 kB
text/typescript
import { z } from 'astro/zod';
import type { SchemaContext } from 'astro:content';
import { IconSchema } from './icon';
export const HeroSchema = ({ image }: SchemaContext) =>
z.object({
/**
* The large title text to show. If not provided, will default to the top-level `title`.
* Can include HTML.
*/
title: z.string().optional(),
/**
* A short bit of text about your project.
* Will be displayed in a smaller size below the title.
*/
tagline: z.string().optional(),
/** The image to use in the hero. You can provide either a relative `file` path or raw `html`. */
image: z
.union([
z.object({
/** Alt text for screenreaders and other assistive technologies describing your hero image. */
alt: z.string().default(''),
/** Relative path to an image file in your repo, e.g. `../../assets/hero.png`. */
file: image(),
}),
z.object({
/** Alt text for screenreaders and other assistive technologies describing your hero image. */
alt: z.string().default(''),
/** Relative path to an image file in your repo to use in dark mode, e.g. `../../assets/hero-dark.png`. */
dark: image(),
/** Relative path to an image file in your repo to use in light mode, e.g. `../../assets/hero-light.png`. */
light: image(),
}),
z
.object({
/** Raw HTML string instead of an image file. Useful for inline SVGs or more complex hero content. */
html: z.string(),
})
.transform(({ html }) => ({ html, alt: '' })),
])
.optional(),
/** An array of call-to-action links displayed at the bottom of the hero. */
actions: z
.object({
/** Text label displayed in the link. */
text: z.string(),
/** Value for the link’s `href` attribute, e.g. `/page` or `https://mysite.com`. */
link: z.string(),
/** Button style to use. One of `primary` (the default), `secondary`, or `minimal`. */
variant: z.enum(['primary', 'secondary', 'minimal']).default('primary'),
/**
* An optional icon to display alongside the link text.
* Can be an inline `<svg>` or the name of one of Starlight’s built-in icons.
*/
icon: z
.union([IconSchema(), z.string().startsWith('<svg')])
.transform((icon) => {
const parsedIcon = IconSchema().safeParse(icon);
return parsedIcon.success
? ({ type: 'icon', name: parsedIcon.data } as const)
: ({ type: 'raw', html: icon } as const);
})
.optional(),
/** HTML attributes to add to the link */
attrs: z.record(z.union([z.string(), z.number(), z.boolean()])).optional(),
})
.array()
.default([]),
});