AstroGlass features a highly flexible dynamic theming system built on top of Tailwind CSS v4 and Astro’s component architecture.
Architecture Overview
The theming system consists of three main layers:
- Theme Registry: Definitions for each theme in
src/config/themes.ts. - CSS Custom Properties: Theme-aware variables defined in
src/styles/_themes.css. - Dynamic Rendering: The
[theme].astropage dynamically renders the correct component variant for each section.
Theme Registry
Every theme is registered in src/config/themes.ts. This centralizes theme metadata and makes it available to the entire application.
- src/
- config/
- themes.ts
- config/
Each theme definition includes:
export const themes: ThemeDefinition[] = [ { id: 'liquid', name: 'Liquid', color: 'from-blue-500 to-cyan-400', // Tailwind gradient classes icon: '💧', sections: ['Header', 'Hero', 'About', 'Features', 'Portfolio', 'Pricing', 'Testimonial', 'FAQ', 'CTA', 'Contact', 'Footer'], enabled: true, premium: false, description: 'Fluid, organic design with smooth animations', }, // Glass, Neo, Luxury, Minimal, Aurora...];CSS Variables
Theme-specific colors and effects are controlled through CSS custom properties. Variables are scoped to a data-theme attribute on the <html> or <body> tag.
[data-theme="liquid"] { --p: 260 80% 60%; /* Primary */ --s: 310 80% 60%; /* Secondary */ --a: 190 90% 60%; /* Accent */ --b1: 220 20% 10%; /* Base background */ --bc: 220 20% 90%; /* Base content (text) */}Components consume these via hsl(var(--p)) or Tailwind utilities:
<div class="bg-[hsl(var(--p))] text-[hsl(var(--bc))]"> Themed Content</div>Variables use short names (--p, --s, --a, --b1, --bc, --er, --su) to stay consistent with the DaisyUI-inspired naming convention used throughout the project.
Dynamic Component Rendering
Theme pages are rendered by src/pages/[theme].astro. This file uses a component map to dynamically select the correct variant for each section:
---const componentMap = { liquid: { Header: HeaderLiquid, Hero: HeroLiquid, About: AboutLiquid, Features: FeaturesLiquid, // ... all 11 sections }, glass: { /* ... */ }, neo: { /* ... */ }, luxury: { /* ... */ }, minimal: { /* ... */ }, aurora: { /* ... */ },};
const components = componentMap[themeId];---
<components.Header /><components.Hero /><components.About /><!-- ... -->Each section variant is a self-contained Astro component. It uses useTranslations() internally for all text — no external props are needed. This allows each theme to have completely different HTML structures while maintaining a uniform API.
Creating a New Theme
-
Add Theme Definition
Add the theme definition object to
src/config/themes.ts. -
Define CSS Variables
Define the new theme’s CSS variables in
src/styles/_themes.css. -
Create Section Components
Create theme-specific component variants for each section, e.g.,
src/components/sections/hero/HeroMyTheme.astro. -
Register in Component Map
Add the new theme’s components to the
componentMapinsrc/pages/[theme].astro. -
Add Translations
Add any new localized strings to the JSON files in
src/locales/.