README.theme.md

November 24, 2025 · View on GitHub

Showcase Card

astro-erudite

Stargazers License

astro-erudite is an opinionated, unstyled static blogging template built with Astro, Tailwind, and shadcn/ui. Extraordinarily loosely based off the Astro Micro theme by trevortylerlee.

Preview 1Preview 2
Preview 3Preview 4

Note

To learn more about why this template exists, read The State of Static Blogs in 2024, where I share my take on what constitutes a great blogging template and my goals while developing this one.


Community Examples

Below are some fantastic examples of websites based on this template. If you wish to add your site to this list, open a pull request!

SiteAuthorDescription/FeaturesSource
enscribe.dev@jktrnHeavily modified bento-style homepage with client interactivity, with custom MDX components!
emile.sh@echoghiA minimalist personal blog using the flexoki theme
decentparadox.me@decentparadoxA heavily customized personal portfolio with a sci-fi theme!
flocto.github.io@floctoA slightly modified personal blog
dumbprism.me@dumbprismA customized portfolio inspired by enscribe's bento grid style adding my gist of UI
hyuki.dev@snow0406A minimalist blog with a blue color scheme, focusing on simplicity!
ldd.cc@xJoyLuThe cream of the idlers.
rezarezvan.com@rezaarezvanA academic blog with personal touches :).
blog.z0x.ca@z0xVery minimal version of erudite, stripping it down to the bare essentials
angelaytchan.net@wispyplantAn artist portfolio and activities archive
kaezr.xyz@kaezrrA minimal porfolio and blog website with slight tweaks to the original.
worldwidewong@brendanwong-webA slightly funky portfolio, blog, and resume site with an added photo gallery.
bgajjala.dev@bgajjala8A minimal blog featuring a paper-color inspired color scheme
ankitz007.vercel.app@ankitz007A personal blog with a few modifications and updates to the original.
sadman.ca@sadmancaA customized personal blog with: Goodreads reading progress tracker, SVG thumbnails, custom heading styles, and dynamic media grids (books, movies, etc.)
marcel-to.vercel.app@Marcel-TOA content‑driven personal portfolio showcasing software projects, deep–dive blog series and multi-part project documentation.

Features

  • Astro's Islands architecture for selective hydration and client-side interactivity while maintaining fast static site rendering.
  • shadcn/ui with Tailwind color conventions for automatic light and dark theme styling. Features accessible, theme-aware UI components for navigation, buttons, and more.
  • Expressive Code for enhanced code block styling, syntax highlighting, and code block titles.
  • Blog authoring with MDX for component-rich content and LaTeX\LaTeX math rendering via KaTeX.
  • Astro View Transitions in SPA mode for smooth route animations.
  • SEO optimization with granular metadata and Open Graph tag control for each post.
  • RSS feed and sitemap generation.
  • Subpost support for breaking long content into digestible parts and organizing related series.
  • Author profiles with a dedicated authors page and multi-author post support.
  • Project tags with a dedicated tags page for post categorization and discovery.
  • Custom Callout component variants for enhanced technical writing.

Repository Structure at a Glance

AreaPurpose
src/consts.tsCentralizes site metadata, navigation, social links, and an icon lookup map for consistent branding across the site.
src/content.config.tsDeclares Astro content collections for blog posts, authors, and projects with Zod schemas that validate frontmatter.
src/content/Houses MDX and Markdown content grouped by collection; the README inside explains required frontmatter fields.
src/layouts/Layout.astroProvides the global page shell, wiring shared CSS, header, footer, and optional slots for head metadata, navigation, and TOCs.
src/components/Astro components for site chrome (header, footer, breadcrumbs, cards, callouts) that consume data from consts.ts and lib helpers.
src/components/ui/Reusable React components powered by class-variance-authority and the shared cn helper for consistent styling.
src/lib/Data and formatting utilities—including loaders for posts/authors/tags, reading-time calculations, TOC builders, and date helpers.
src/pages/File-based routes that fetch content through the lib helpers, render Astro/React components, and slot optional sidebars.
src/styles/global.cssTailwind 4 setup with Flexoki-inspired tokens, font imports, and light/dark theme variables.
public/Static assets such as favicons, fonts, OG fallbacks, and showcase imagery.
scripts/TypeScript automation for generating posts, favicons, OG images, and other design assets (see scripts/README.md).

How the Pieces Fit Together

  1. Content ingestion – MDX/Markdown files are validated against content.config.ts, then loaded through src/lib/data-utils.ts, which handles draft filtering, sorting, subpost hierarchies, reading times, and TOC extraction.
  2. Site chrome & themingsrc/layouts/Layout.astro wraps every page in shared CSS, header, and footer components. The header reads navigation/social metadata from src/consts.ts, while ThemeToggle.astro keeps light/dark selections in sync across view transitions.
  3. Page metadatasrc/components/PageHead.astro and src/components/PostHead.astro consolidate canonical URLs, SEO tags, and Open Graph/Twitter metadata, falling back to shared OG imagery when a post omits one.
  4. UI building blocks – Astro and React components (cards, callouts, pagination, buttons) compose Tailwind tokens with class-variance-authority and the shared cn helper, keeping styling predictable.
  5. Routing & presentation – Files in src/pages/ map directly to routes, orchestrating data fetching, layout slots, breadcrumb generation, and optional TOC sidebars for blog posts and subposts.

Tooling & Configuration Highlights

  • astro.config.ts enables integrations for MDX, React islands, sitemap generation, Expressive Code, Astro Icon, Tailwind, KaTeX, emoji, and sets the dev server to localhost:1234.
  • package.json scripts coordinate builds, OG image generation, Astro type-checking, and content scaffolding (for example, npm run new-post).
  • Automation scripts in scripts/ render OG assets, favicons, and logos via the React templates in src/components/ui/ using Satori and Resvg.

Next Steps for New Contributors

  • Customize branding and navigation – Update src/consts.ts with your title, description, navigation tabs, and social links; tweak theme tokens in src/styles/global.css for your color system.
  • Author new content quickly – Follow the content README guidance or run npm run new-post to scaffold MDX files that satisfy collection schemas and generate matching OG assets.
  • Understand dynamic behavior – Review src/lib/data-utils.ts alongside src/pages/posts/[...id].astro to see how subposts, TOCs, and metadata are composed when rendering individual posts.
  • Extend the component library – Use the shadcn-inspired React components in src/components/ui/ and Astro wrappers (like Callout.astro or BlogCard.astro) as references for building new interactive or MDX-friendly UI.
  • Tinker with build tooling – Modify astro.config.ts or augment the automation scripts if you need additional markdown processing, asset generation, or linting during the build.

Technology Stack

This is a list of the various technologies used to build this template:

CategoryTechnology Name
FrameworkAstro
StylingTailwind
Componentsshadcn/ui
ContentMDX
CodeblocksExpressive Code, Shiki
GraphicsFigma
DeploymentVercel

Getting Started

  1. Hit “Use this template”, the big green button on the top right, to create a new repository in your own GitHub account with this template.

  2. Clone the repository:

    git clone https://github.com/[YOUR_USERNAME]/[YOUR_REPO_NAME].git
    cd [YOUR_REPO_NAME]
    
  3. Install dependencies:

    npm install
    
  4. Start the development server:

    npm run dev
    
  5. Open your browser and visit http://localhost:1234 to get started. The following commands are also available:

    CommandDescription
    npm run startAlias for npm run dev
    npm run buildRun type checking and build the project
    npm run previewPreviews the built project
    npm run astroRun Astro CLI commands
    npm run prettierBlanket format all files using Prettier

Customization

Site Configuration

Edit the src/consts.ts file to update your site's metadata, navigation links, and social links:

export const SITE: Site = {
  title: 'astro-erudite',
  description: // ...
  href: 'https://astro-erudite.vercel.app',
  featuredPostCount: 2,
  postsPerPage: 3,
}

export const NAV_LINKS: SocialLink[] = [
  {
    href: '/posts',
    label: 'posts',
  },
  // ...
]

export const SOCIAL_LINKS: SocialLink[] = [
  {
    href: 'https://github.com/jktrn',
    label: 'GitHub',
  },
  // ...
]

Color Palette

Colors are defined in src/styles/global.css in OKLCH format, using the shadcn/ui convention:

:root {
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --secondary: oklch(0.97 0 0);
  --secondary-foreground: oklch(0.205 0 0);
  --muted: oklch(0.97 0 0);
  --muted-foreground: oklch(0.556 0 0);
  --accent: oklch(0.97 0 0);
  --accent-foreground: oklch(0.205 0 0);
  --destructive: oklch(0.577 0.245 27.325);
  --border: oklch(0.922 0 0);
  --ring: oklch(0.708 0 0);
}

[data-theme='dark'] {
  /* ... */
}

Favicons

Favicons are generated using RealFaviconGenerator. To adjust the favicons, replace the files in the public/ directory (such as favicon.ico, favicon.svg, apple-touch-icon.png, etc.) with your own. After updating the favicon files, you'll also need to adjust the references in src/components/Favicons.astro to match your new favicon filenames and paths:

<!-- Replace these with the generated meta tags -->
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<meta name="apple-mobile-web-app-title" content="astro-erudite" />
<link rel="manifest" href="/site.webmanifest" />

Adding Content

Blog Posts

Add new blog posts as MDX files in the src/content/blog/ directory. Use the following frontmatter structure:

---
title: 'Your Post Title'
description: 'A brief description of your post!'
date: 2024-01-01
tags: ['tag1', 'tag2']
image: './image.png'
authors: ['author1', 'author2']
draft: false
---

The blog post schema is defined as follows:

FieldType (Zod)RequirementsRequired
titlestringShould be ≤60 characters.Yes
descriptionstringShould be ≤155 characters.Yes
datecoerce.date()Must be in YYYY-MM-DD format.Yes
ordernumberSort order for subposts with the same date. Defaults to 0 if not provided.Optional
imageimage()Should be exactly 1200px × 630px.Optional
tagsstring[]Preferably use kebab-case for these.Optional
authorsstring[]If the author has a profile, use the id associated with their Markdown file in src/content/authors/ (e.g. if their file is named jane-doe.md, use jane-doe in the array).Optional
draftbooleanDefaults to false if not provided.Optional

Authors

Add author information in src/content/authors/ as Markdown files. A file named [author-name].md can be associated with a blog post if "author-name" (the id) is added to the authors field:

---
name: 'enscribe'
pronouns: 'he/him'
avatar: 'https://gravatar.com/avatar/9bfdc4ec972793cf05cb91efce5f4aaaec2a0da1bf4ec34dad0913f1d845faf6.webp?size=256'
bio: 'd(-_-)b'
website: 'https://enscribe.dev'
twitter: 'https://twitter.com/enscry'
github: 'https://github.com/jktrn'
mail: 'jason@enscribe.dev'
---

The author schema is defined as follows:

FieldType (Zod)RequirementsRequired
namestringn/aYes
pronounsstringn/aOptional
avatarstring.url() or string.startsWith('/')Should be either a valid URL or a path starting with /. Preferably use Gravatar with the ?size=256 size parameter.Yes
biostringn/aOptional
mailstring.email()Must be a valid email address.Optional
websitestring.url()Must be a valid URL.Optional
twitterstring.url()Must be a valid URL.Optional
githubstring.url()Must be a valid URL.Optional
linkedinstring.url()Must be a valid URL.Optional
discordstring.url()Must be a valid URL.Optional

Tip

You can add as many social media links as you want, as long as you adjust the schema! Make sure you also support the new field in the src/components/SocialIcons.astro component.

Projects

Add projects in src/content/projects/ as Markdown files:

---
name: 'Project A'
description: 'This is an example project description! You should replace this with a description of your own project.'
tags: ['Framework A', 'Library B', 'Tool C', 'Resource D']
image: '/static/1200x630.png'
link: 'https://example.com'
startDate: '2024-01-01'
endDate: '2024-01-01'
---

The project schema is defined as follows:

FieldType (Zod)RequirementsRequired
namestringn/aYes
descriptionstringn/aYes
tagsstring[]n/aYes
imageimage()Should be exactly 1200px × 630px.Yes
linkstring.url()Must be a valid URL.Yes
startDatecoerce.date()Must be in YYYY-MM-DD format.Optional
endDatecoerce.date()Must be in YYYY-MM-DD format.Optional

License

This project is open source and available under the MIT License.


Star History

Star History Chart

Built with ♥ by enscribe!