Skip to content

Author API

Default Structure

  • Directorypackage/
    • Directorypublic/
    • Directorysrc/
      • Directoryassets/
      • Directorycomponents/
      • Directorylayouts/
      • Directorypages/
      • Directorystyles/
    • index.ts
    • package.json
package/index.ts
import { z } from 'astro/zod'
import defineTheme from 'astro-theme-provider';
export default defineTheme({
name: "my-theme",
schema: z.object({
title: z.string(),
description: z.sting().optional()
})
})

Options Reference

name

Type: string

Required

The name of a theme, must be unique. If you are authoring your theme as a package, it is recomended to use the package name as the name of your theme.

schema

Type: Zod Schema

Default: ZodTypeAny

A zod schema for validating the default value of a theme’s config module. The schema must be JSON serializable.

Example:

schema: z.object({
title: z.string(),
description: z.string().optional()
})
---
import config from "my-theme:config"
console.log(config.title, config.description)
---

srcDir

Type: string

Default: "src"

Directory that contains a theme’s assets (pages, components, images, css, etc). Assets inside the src directory can be accessed using virtual modules (see imports).

pageDir

Type: string | AstroPagesOption

Default: "pages"

Directory that contains all of the pages for a theme.

publicDir

Type: string | AstroPublicOption

Default: "public"

Directory that contains a theme’s static assets (favicon.svg, etc). By default, these assets act as placeholders and can be overwritten by assets located in a user’s public real folder.

middlewareDir

Type: string | false

Default: srcDir

Directory that contains a theme’s middleware. Relative paths are resolved relative to the theme’s srcDir, use false to disable middleware injection.

integrations

Type: Array<AstroIntegration | (options: { config: z.infer<Schema>, integrations: string[] }) => AstroIntegration | false | null | undefined>

An array of integrations that will be included with the theme:

integrations: [
mdx(),
sitemap(),
]
integrations: [
// Check for other integrations
({ integrations }) => {
if (!integrations.contains('@astrojs/sitemap')) {
return inoxsitemap()
}
},
]
integrations: [
// Pass user options to integrations
({ config }) => {
if (config.sitemap) {
return inoxsitemap(config.sitemap)
}
},
]

imports

Type: Record<string, Record<string, string> | string[] | string | false>

Default:

imports: {
assets: "assets**.{jpeg,jpg,png,tiff,webp,gif,svg,avif}",
components: "components/**.{astro,tsx,jsx,svelte,vue}",
layouts: "layouts/**.astro",
styles: "styles/**.{css,scss,sass,styl,less}",
}

Create virtual modules to access assets inside a theme and allow users to override them.

false:

Toggle default virtual modules off

imports: {
assets: false,
components: false,
layouts: false,
styles: false,
}

string:

Glob files into a virtual module, glob patterns are relative to a theme’s srcDir.

  • Directorypackage/
    • Directorysrc/
      • Directorycomponents/
        • Hero.astro
        • Card.astro
        • Button.astro
imports: {
components: "components/**.astro",
}
import { Hero, Card, Button } from "my-theme:components"

array:

Use an array to combine imports into a single virtual module.

imports: {
styles: [
"./src/styles/reset.css",
"./src/styles/global.css",
"./src/styles/utils.css",
],
}
import "my-theme:styles"

object:

Use an object to create more complex custom virtual modules.

imports: {
components: {
imports: [ "./src/styles/global.css" ],
default: "./src/layout/Layout.astro",
Head: "./src/components/Head.astro",
Button: "./src/components/Button.astro"
}
}
import Layout, { Head, Button } from "my-theme:components"

log

Type: "verbose" | "minimal" | boolean

Default: true

Toggle logging for the theme.

LevelDescription
falseZero logging
"minimal" | trueLog warnings
"verbose"Log everything, including debug information

entrypoint

Type: string

Default: directory of the file the theme is exported from

A path to the root directory, or file inside the root directory, of a theme.

Virtual Module Reference

theme:config

A virtual module used to expose the user configuration. The shape for this module can be define using the schema option:

import { z } from 'astro/zod'
import defineTheme from 'astro-theme-provider';
export default defineTheme({
name: "my-theme",
schema: z.object({
title: z.string(),
description: z.sting().optional()
})
})

After a schema is defined, authors can use this virtual module to create configurable pages and components:

---
import config from "my-theme:config"
---
<h1>{config.title}</h1>
<p>{config.description}</p>

theme:context

A virtual module that contains utilities and information related to the context or enviroment a theme is running in.

declare module "theme:context" {
export const pages: Map<string, string>;
export const integrations: Set<string>;
}

pages

A Map that contains the final pattern that page is injected with:

---
import { pages } from "my-theme:context"
---
{ pages.get('/blog') &&
<a href={pages.get('/blog')}>Blog</a>
}

integrations

A Set that contains the name of every integration inside the user’s project.

---
import { integrations } from "my-theme:context"
---
{ integrations.get('@astrojs/rss') &&
<a href='/rss.xml'>RSS</a>
}

theme:layouts

By default, all Astro files inside a theme’s src/layouts folder are available as named exports inside the :layouts module.

  • Directorypackage/
    • Directorysrc/
      • Directorylayouts/
        • Layout.astro
import { Layout } from "my-theme:layouts";

This virtual module can be configured using the imports option.

theme:components

By default, all Astro files inside a theme’s src/components folder are available as named exports inside the :components module.

  • Directorypackage/
    • Directorysrc/
      • Directorycomponents/
        • Hero.astro
        • Card.astro
        • Button.astro
import { Hero, Card, Button } from "my-theme:components";

This virtual module can be configured using the imports option.

theme:assets

By default, all images inside a theme’s src/assets folder are available as named exports inside the :assets module.

  • Directorypackage/
    • Directorysrc/
      • Directoryassets/
        • logo.png
        • background.png
import { logo, background } from "my-theme:assets";

This virtual module can be configured using the imports option.

theme:styles

By default, all styles inside a theme’s src/styles folder are available inside the :styles module.

  • Directorypackage/
    • Directorysrc/
      • Directorystyles/
        • reset.css
        • styles.css
        • utilities.css
import "my-theme:styles";

This virtual module can be configured using the imports option.

Read more:

Example Project

Author a theme inside a package similar to a normal project:

  • Directorypackage/
    • Directorypublic/
      • favicon.svg
    • Directorysrc/
      • Directoryassets/
        • logo.png
      • Directorycomponents/
        • Card.astro
      • Directorylayouts/
        • Layout.astro
      • Directorypages/
        • index.astro
      • Directorystyles/
        • global.css
    • index.ts
    • package.json
    • README.md

Export the theme integration from the package entrypoint:

package/index.ts
import { z } from 'astro/zod';
import defineTheme from 'astro-theme-provider';
export default defineTheme({
name: "my-theme",
schema: z.object({
title: z.string(),
description: z.string().optional()
})
})

Use the generated virtual modules to author the theme:

package/src/pages/index.astro
---
import { Layout } from 'my-theme:layouts';
import { Card } from 'my-theme:components';
import { logo } from 'my-theme:assets';
import config from 'my-theme:config';
import 'my-theme:styles';
const {
title,
description = "Welcome to my theme"
} = config
---
<Layout>
<Card {title} {description} img={logo}/>
</Layout>