Skip to content

Themes & Plugins

Built-in: default, dark, minimal, corporate, gradient, rose, forest. Set one per deck in _config.json:

{ "theme": "gradient" }

A theme is CSS scoped to [data-theme="<name>"] that sets Astlide’s custom properties:

themes/my-theme.css
[data-theme="my-theme"] {
--color-background: #fef3c7;
--color-foreground: #78350f;
--color-primary: #d97706;
--color-secondary: #92400e;
--color-accent: #fbbf24;
--color-muted: #fde68a;
--code-background: #451a03;
}

Register it through a plugin (below), then set "theme": "my-theme" in the deck’s _config.json.

A .pptx / .potx / .thmx template can be a theme too — its backgrounds, fonts, colors and placeholder positions: astlide({ templates: { brand: './brand.pptx' } }). See PowerPoint templates.

Plugins contribute themes, layouts, transitions, Shiki languages / themes and slide decorators.

astro.config.mjs
import { defineConfig } from "astro/config";
import astlide from "@astlide/core";
import { defineAstlidePlugin } from "@astlide/core/plugin";
const myPlugin = defineAstlidePlugin({
name: "astlide-plugin-midnight",
themes: [{ name: "midnight", cssEntrypoint: "./themes/midnight.css" }],
layouts: [{ name: "split-quote" }],
transitions: [{ name: "iris" }],
shiki: {
langs: [/* additional Shiki langs */],
themes: [{ name: "neon-night" /* shiki theme JSON */ }],
},
});
export default defineConfig({
integrations: [astlide({ plugins: [myPlugin] })],
});

cssEntrypoint is resolved as a Vite import — any module specifier that resolves to CSS works (relative path, npm package, …).

A layout can register a name only (a .slide-<name> class is applied so plugin CSS can target it), or supply a componentEntrypoint so a plugin .astro component owns the slide markup:

layouts: [
{ name: "split-quote", componentEntrypoint: "astlide-plugin-acme/SplitQuote.astro" },
],
Field Value
Package name astlide-plugin-* or @scope/astlide-plugin-*
keywords include "astlide-plugin"
peerDependencies { "@astlide/core": "^x.y" }
Default export defineAstlidePlugin({ … })

Render a component on every slide — logo, footer, page number, back link — without editing each file:

astlide({ slideDecorators: ["./src/components/DeckFooter.astro"] });

Plugins can contribute decorators too (decorators: [{ componentEntrypoint: "…" }]).

Read the deck name, slide number, total, layout, transition and parsed config:

---
// server-side, inside any slide component or decorator
import { getDeckContext } from "@astlide/core/context";
const ctx = getDeckContext(Astro);
---
<footer>{ctx?.config.title} — {ctx?.slideNumber}/{ctx?.totalSlides}</footer>

In the browser, getClientDeckContext() returns the same shape.

Astlide injects Inter (text) and JetBrains Mono (code) from Google Fonts by default, so slides and exported PDFs use the same fonts on every machine:

astlide({ font: false }); // use whatever your CSS specifies
astlide({ font: "https://fonts.googleapis.com/css2?family=IBM+Plex+Sans&display=swap" });

Astlide serves a deck index at /. If you add your own src/pages/index.{astro,md,mdx,html}, Astlide detects it and skips its index route. Force either way with injectIndexRoute: false | true.