Skip to content

Accessible Astro Starter

The Accessible Astro Starter is a ready-to-use, SEO and accessibility-friendly blogging theme. It provides a solid foundation with numerous accessible components, Tailwind CSS integration, and example pages including a dynamic blog, 404 page, and MDX support. The theme features a centralized configuration system, an integrated command launcher for keyboard-driven navigation, and comprehensive accessibility preference toggles.

  • Built on Astro 5.16+
  • Tailwind CSS 4.1+ integration
  • Centralized theme configuration via theme.config.ts
  • Command launcher with keyboard navigation (Cmd/Ctrl+K)
  • Dynamic theme colors configurable from a single config file
  • Modern OKLCH color system with light/dark mode
  • Improved SEO with astro-seo package
  • Atkinson Hyperlegible font for improved readability
  • Markdown and MDX support with examples included
  • Excellent Lighthouse/PageSpeed scores
  • ESLint with strict accessibility settings
  • Prettier integration with plugins for Astro and Tailwind
  • View Transitions support
  • Dynamic blog with pagination and breadcrumbs
  • Enhanced portfolio page with rich media support
  • Custom 404 error page
  • TypeScript interfaces and proper prop typing
  • Semantic HTML landmarks (header, main, footer, nav, etc.)
  • Proper heading hierarchy
  • ARIA attributes for enhanced screen reader support
  • Keyboard-accessible navigation with dropdown support
  • Command launcher with full keyboard navigation (Cmd/Ctrl+K)
  • Skip links for main menu and content
  • Dark mode with system preference detection
  • High Contrast mode toggle for enhanced visual clarity
  • Reduced Motion mode toggle respecting user preferences
  • Focus indicators that work on all backgrounds
  • Screen reader only text utilities
  • Accessible components like Accordions, Breadcrumbs, Modals, and more
  • Color Contrast Checker component for accessibility testing
  • Modern CSS with logical properties
  1. Clone the repository:

    Terminal window
    git clone https://github.com/incluud/accessible-astro-starter.git
  2. Install dependencies:

    Terminal window
    npm install
  3. Start development server:

    Terminal window
    npm run dev
  4. Open your browser: Visit http://localhost:4321 to see your site in action.

The starter follows a clear and organized structure:

  • Directorypublic/
    • Directoryfonts/
    • // Other assets
  • Directorysrc/
    • Directoryassets/
      • Directoryimg/ // Contains the logo and social preview
      • Directoryscss/
        • Directorybase/ // Core styles and utilities
    • Directorycomponents/
      • CallToAction.astro
      • ContentMedia.astro
      • Counter.astro
      • Feature.astro
      • Footer.astro
      • Header.astro
      • Hero.astro
      • LauncherConfig.astro // Command launcher configuration
      • Navigation.astro
      • NavigationItems.astro // Dynamic navigation from config
      • ResponsiveToggle.astro
    • Directorycontent/
      • Directoryprojects/
        • project-01.mdx
        • // Project content files
    • Directorylayouts/
      • DefaultLayout.astro // Includes SEO via astro-seo
      • MarkdownLayout.astro
    • Directorypages/
      • Directoryblog/
        • […page].astro // Dynamic blog pages
        • [post].astro // Individual post pages
      • Directoryportfolio/
        • […page].astro
        • [project].astro
      • 404.astro
      • accessible-components.astro
      • accessible-launcher.astro // Launcher demo page
      • accessibility-statement.mdx
      • index.astro
      • markdown-page.md
      • mdx-page.mdx
    • Directoryutils/
      • defineThemeConfig.ts // Theme config utility
  • theme.config.ts // Centralized theme configuration
  • package.json
  • astro.config.mjs
CommandAction
npm installInstall dependencies
npm run devStart dev server at localhost:4321
npm run buildBuild for production
npm run previewPreview production build

The starter includes several pre-built accessible components:

  • CallToAction.astro - Styled block with a button
  • ContentMedia.astro - Content with media layout
  • Counter.astro - Icon and number counter
  • Feature.astro - Feature highlight component
  • Footer.astro - With customizable content
  • Header.astro - With responsive navigation and launcher
  • Hero.astro - Hero section component
  • Navigation.astro - Keyboard accessible dropdown navigation
  • NavigationItems.astro - Dynamic navigation items from theme config
  • ResponsiveToggle.astro - Mobile navigation toggle
  • ColorContrast.astro - Accessibility testing component for color contrast
  • PageHeader.astro - Consistent page titles component
  • Logo.astro - Standardized branding component
  • BlockQuote.astro - Content citation component
  • BreakoutImage.astro - Full-width image component
  • SocialShares.astro - Blog post sharing component
  • FeaturedPosts.astro - Showcase featured blog posts
  • FeaturedProjects.astro - Showcase featured projects
  • LauncherConfig.astro - Command launcher configuration with preferences, navigation, blog posts, projects, and socials

The starter uses a centralized theme configuration system. All site-wide settings are managed in a single theme.config.ts file at the project root.

theme.config.ts
import { defineThemeConfig } from '@utils/defineThemeConfig'
import previewImage from '@assets/img/social-preview-image.png'
import logoImage from '@assets/img/logo.svg'
export default defineThemeConfig({
name: 'My Awesome Site',
id: 'my-awesome-site',
logo: logoImage,
seo: {
title: 'My Awesome Site',
description: 'A website built with Accessible Astro Starter',
author: 'Your Name',
image: previewImage,
},
colors: {
primary: '#d648ff',
secondary: '#00d1b7',
neutral: '#b9bec4',
outline: '#ff4500',
},
navigation: {
darkmode: true,
items: [
// Navigation items...
],
},
socials: [
// Social links...
],
})
seo: {
title: 'Site Title', // Used in <title> and OG tags
subtitle: 'Optional Subtitle', // Appended to title when present
description: 'Site description for SEO',
author: 'Author Name',
image: previewImage, // ImageMetadata or string path
}

The starter includes the Accessible Astro Launcher component - a keyboard-driven command palette for quick navigation and accessibility preferences.

  • Keyboard shortcut: Press Cmd + K (Mac) or Ctrl + K (Windows/Linux)
  • Click trigger: Click the search field in the navigation bar

The launcher provides quick access to:

  • Preferences: Toggle Dark Mode, High Contrast, and Reduced Motion
  • Navigation: All pages defined in your theme configuration
  • Blog Posts: Dynamically loaded from your blog API (if configured)
  • Projects: Your portfolio projects from content collections
  • Socials: Links to your social profiles

The launcher is configured in src/components/LauncherConfig.astro and automatically reads from your theme.config.ts:

src/components/LauncherConfig.astro
---
import { Launcher, LauncherList, LauncherItem, LauncherGroup } from 'accessible-astro-launcher'
import themeConfig from '@theme-config'
// Navigation items are automatically loaded from theme config
const launcherNavigationItems = themeConfig.navigation.items.flatMap((item) => {
if (item.excludeFromLauncher) return []
// ... processes navigation items
})
---
<Launcher id="site-launcher">
<LauncherList>
<LauncherGroup label="Preferences">
<!-- Preference toggles -->
</LauncherGroup>
<LauncherGroup label="Navigate to">
<!-- Navigation items from config -->
</LauncherGroup>
<!-- Additional groups for blog, projects, socials -->
</LauncherList>
</Launcher>

To enable dynamic blog posts in the launcher, set the BLOG_API_URL environment variable:

.env
BLOG_API_URL=https://your-blog-api.com/posts.json

The theme uses Tailwind CSS with additional SCSS utilities. Customize your theme in the following files:

  • Directorysrc/
    • Directoryassets/
      • Directoryscss/
        • Directorybase/
          • _reset.scss // CSS reset
          • _breakpoints.scss // Media queries
          • _buttons.scss // Button styles
          • _colors.scss // Color system
          • _font.scss // Typography
          • _outline.scss // Focus styles
          • _root.scss // Custom properties

The starter includes a powerful and versatile breakpoint mixin system using modern CSS media query syntax. The system supports min-width, max-width, and range queries with predefined breakpoints or custom values.

$breakpoints: (
'default': 0,
'xs': 320px,
's': 480px,
'm': 768px,
'l': 1024px,
'xl': 1280px,
'2xl': 1536px,
'nav': 1000px,
)
// Apply styles from medium screens and up
.component {
@include breakpoint('m') {
font-size: 1.2rem;
padding: 2rem;
}
}
// Output: @media (width >= 768px) { ... }

The starter includes a powerful OKLCH-based color system that makes it incredibly easy to create accessible color schemes. You only need to define your brand colors in theme.config.ts, and the entire color palette is automatically generated!

:root {
// Just set these three brand colors in hex or any format
--brand-primary: #d648ff; // Your primary brand color
--brand-secondary: #00d1b7; // Your secondary brand color
--brand-neutral: #b9bec4; // Your neutral brand color
// The rest of the color palette is automatically generated!
}

The magic of this system is how it leverages OKLCH color transformations to create consistent, harmonious color palettes with proper contrast for accessibility. OKLCH (Lightness, Chroma, Hue) is a perceptually uniform color space that makes it easier to create accessible color combinations.

The starter uses the astro-seo package for SEO management, integrated directly in DefaultLayout.astro. Pass SEO props to any page through the layout:

---
import DefaultLayout from '../layouts/DefaultLayout.astro'
---
<DefaultLayout
title="My Page"
description="Page description"
image="/my-image.png"
>
<!-- Page content -->
</DefaultLayout>
PropTypeDescription
titlestringPage title
descriptionstringPage description
urlstringCanonical URL (defaults to current URL)
imageImageMetadata | stringSocial sharing image
authorstringPage author
type'website' | 'article'Open Graph type
useTitleTemplatebooleanWhether to append site name (default: true)

Default values for these props are pulled from your theme.config.ts SEO settings.

  1. Fork the repository on GitHub

  2. Create a new branch:

    Terminal window
    git checkout -b feat/your-feature-name
  3. Make your changes and commit them:

    Terminal window
    git commit -m "Add some feature"
  4. Push to your fork:

    Terminal window
    git push origin feat/your-feature-name
  5. Open a Pull Request on GitHub