A modern, responsive blog theme for Astro with support for tags, categories, series, and featured posts. This theme is designed to be fast, SEO-friendly, and easy to customize.
- π Built with Astro - Benefit from Astro's speed and flexibility
- π± Fully Responsive - Looks great on all devices
- π¨ Customizable - One logo-anchored accent ramp and swappable font tokens drive links, buttons, focus rings, and chips, and one config file (
src/config/site.ts) owns identity, hero, homepage, footer, and page copy - π SEO Optimized - Meta tags, Open Graph, and JSON-LD
- π Blog Ready - Support for posts, categories, tags, and series
- β Featured Posts - An optional
featuredflag surfaces editor's picks in a three-column homepage grid - π§© Homepage Sections - Hero, Featured, Latest, Learning paths, Explore, and Popular Topics, with the hero, featured, and latest posts deduped automatically
- π Search Functionality - Client-side search with Fuse.js
- π Pagination - For blog posts, categories, tags, and authors
- π° RSS Feed - Automatically generated RSS feed
- πΊοΈ Sitemap - Automatically generated sitemap
- ποΈ MDX Support - Use components in your markdown
- π€ Typography - Self-hosted display face for headings, system stack for body copy, balanced prose with Tailwind CSS
- π Icons - Easy icon usage with Astro Icon
- π‘ FOUC Prevention - Inline scripts to minimize flash of unstyled content and theme inconsistencies on load.
βββ public/ # Static assets
βββ src/
β βββ assets/ # Images and other assets
β βββ config/ # Site configuration
β βββ content/ # Content collections (blog posts, authors, etc.)
β βββ layouts/ # Layout components
β βββ pages/ # Page components and routes
β βββ styles/ # Global styles
β βββ utils/ # Utility functions
βββ astro.config.mjs # Astro configuration
βββ package.json # Dependencies and scripts
- src/config/: Contains configuration files for the site, menus, and social links
- src/content/: Contains all content collections (blog posts, authors, pages)
- src/layouts/: Contains layout components used throughout the site
- src/pages/: Contains all page components and defines the routing structure
The theme includes several reusable components:
- Layout.astro: Main layout component with header and footer
- PostLayout.astro: Layout for blog posts with metadata and content
- Header/Footer: Navigation and site information
- Pagination: For navigating through multiple pages of content
- Search: Client-side search functionality (requires JavaScript; the index covers roughly the first 4,000 characters of each post body β full-text indexing is deferred, see
src/pages/search.json.ts) - Author Card: Display author information
- Post Card: Display post previews in lists, used by Latest, Featured, archives, and search
- Homepage Sections:
FeaturedPosts,LearningPaths, andPopularTopicscompose the homepage from real content and thehomepageflags insrc/config/site.ts - Tag/Category Cloud: Display and filter by tags or categories
Work through the tasks below in order. Each step links to the reference section with the details.
- Preview the theme. Run
npm install && npm run devand openhttp://localhost:4321. Try the theme toggle, a mobile viewport, the Featured Posts grid, and the MDX widget examples insrc/content/posts/artificial-intelligence-guide.mdx,src/content/posts/vps-hosting-docker-and-caddy.mdx, andsrc/content/posts/developer-seo-checklist.mdx. - Create your site. The fastest path is GitHub's Use this template button; alternatively clone over HTTPS (
git clone https://github.com/bitdoze/bitdoze-astro-theme.git my-blog). Install dependencies on Node 22.12 or newer (see Installation). - Rebrand. Update
src/config/site.tsβ identity, hero, homepage sections, footer titles, and listing/utility page copy β thensrc/config/menu.jsonandsrc/config/social.json(see Configuration). - Create your first content. Add a post, an author, a series, and an ordinary page (see Creating Content and Adding New Pages).
- Remove demo content. Delete the demo posts, authors, and pages you do not need; empty collections render as empty lists rather than failing. The About page is a dedicated content entry at
src/content/about/index.mdβ replace it rather than leaving the placeholder. - Configure contact, origin, and SEO defaults. Set a real contact endpoint (see Contact form), point
SITE_URLat your production origin, and review the metadata defaults insrc/config/site.ts. - Deploy and smoke-test. Build and deploy (see Deployment), then verify navigation, search, RSS, and the custom 404 page on the live host.
- Update from a release. Read CHANGELOG.md before pulling a new version; releases call out any changed configuration or content contracts.
- Node.js 22.12.0 or newer (declared in
package.jsonenginesand pinned in.node-version) - npm 10.8.2 or newer
The theme targets Astro 7.x. When upgrading Astro, check CHANGELOG.md and update the official integrations together.
-
Create your site from this theme β use GitHub's Use this template button, or clone over HTTPS:
git clone https://github.com/bitdoze/bitdoze-astro-theme.git my-blog cd my-blog -
Install dependencies:
npm install
-
Start the development server:
npm run dev
-
Open your browser and visit
http://localhost:4321
Tailor the theme to your needs by updating the following configuration files. Content and copy are not scattered through components: site.ts is the single source for headings, sublines, section titles, and calls to action, and the sibling files own navigation, social links, and contact details.
- Site URL:
- Set the
SITE_URLenvironment variable in production. It falls back tohttps://www.bitdoze.comfor local builds.
- Set the
- Primary Site Metadata & Settings:
- Update
src/config/site.tsfor essential site details such as:- Identity:
title,description,author,brandName,logo, and logo dimensions. - Hero:
hero.title,hero.titleAccent,hero.primaryCta/hero.secondaryCta,hero.statsLabels, andheroDescription. - Homepage: the
showFeaturedPosts/showTaxonomyCards/showPopularTopicstoggles, plus section copy and limits (homepage.featured,homepage.latest,homepage.learningPaths), configured tags (homepage.popularTopics), and the Explore cards (homepage.explore). - Footer: column titles (
footer.exploreTitle,footer.latestTitle). - Pages: headings, meta descriptions, and visible sublines for Blog, Categories, Tags, Authors, Series, Contact, Search, and 404 (
pages.*). ogImage,postsPerPage,favicons, and thenoindexpolicy.
- Identity:
- Update
- Menus:
- Modify
src/config/menu.jsonto define navigation links for the header and footer.
- Modify
- Social Media Links:
- Update
src/config/social.jsonwith your social media profile URLs.
- Update
- Contact Configuration (
src/config/config.json):- Set
params.contact_form_actionto your form endpoint. - Add only the public address, email, and phone details you want displayed.
- The default
"#"action keeps the form disabled with a visible notice β see Contact form.
- Set
The homepage is composed from real content in this order:
- Hero β the newest published post, with proof counts and entry points.
- Featured Posts β up to
homepage.featured.limitposts flaggedfeatured: truein a three-column grid, newest first (the hero post is skipped). - Popular Topics β configured tags with their most recent posts in a full-width band. Columns prefer posts not already shown in the hero or featured grid, then backfill so they still render on small archives; a post never appears in two columns.
- Latest Articles β the newest remaining posts, excluding series and featured entries, with a link to the full archive.
- Learning paths β series in position order plus the largest categories; each path needs at least two entries, with a link to all series.
- Explore Content β links to categories, authors, and tags.
The hero, Popular Topics, and Learning paths render as full-width tinted bands, so the page alternates between white and tinted sections; the footer continues the same surface. Every section's copy, limits, tags, and toggles live in homepage in src/config/site.ts; the header and footer navigation live in src/config/menu.json, and social and contact details in src/config/social.json and src/config/config.json.
Create a new .md or .mdx file in src/content/posts/ with the following frontmatter:
---
title: "Your Post Title"
meta_title: "SEO Title (optional)"
description: "Post description for SEO"
date: 2023-06-01
image: "../../assets/images/your-image.jpg"
authors: ["author-id"]
categories: ["category-name"]
tags: ["tag1", "tag2"]
series:
name: "Series Name"
position: 1
slug: "optional/custom-path"
canonical: "https://example.com/original-article/"
draft: false
featured: true
---
Your post content goes here...Set featured: true to surface a post in the homepage Featured Posts grid
(up to three, newest first, never repeating the hero post). The section is
controlled by homepage.showFeaturedPosts in src/config/site.ts.
Create a new .md file in src/content/authors/ with the following frontmatter:
---
title: "Author Name"
meta_title: "Author Name - Astro Blog Theme"
image: "../../assets/images/authors/author-image.jpg"
description: "Author description"
social:
facebook: "https://facebook.com/username"
twitter: "https://twitter.com/username"
website: "https://example.com"
---
Author bio goes here...This theme uses Tailwind CSS v4 for styling, which emphasizes a CSS-first, minimal-configuration approach.
Key Styling Files:
-
src/styles/global.css: This is the central file for Tailwind CSS setup and custom styles.- Tailwind's core styles (base, components, utilities) are imported via
@import "tailwindcss";. - The
@tailwindcss/typographyplugin is included using@plugin "@tailwindcss/typography";. - You can customize the theme by modifying the CSS variables defined in this file, which control colors, fonts, and other aspects.
- Brand tokens:
--color-accent-50β¦950is the brand ramp (anchored on the logo azure) used for links, buttons, focus rings, chips, and text selection, and--font-displayis the heading face (Bricolage Grotesque, self-hosted inLayout.astro). Body copy stays on the system stack. Override either token in the@themeblock to rebrand. - You can also add your own custom CSS rules here.
- Tailwind's core styles (base, components, utilities) are imported via
-
astro.config.mjs: The@tailwindcss/viteplugin is integrated here, but typically requires no direct configuration for v4 unless you have very specific needs.
Advanced Customization (Optional):
Tailwind CSS v4 is CSS-first and does not automatically detect a tailwind.config.js file. For most customization, stay in src/styles/global.css and use the CSS-first @theme directive:
@theme {
--color-brand: #009cef;
}If you need a legacy JavaScript config (for example, a Tailwind v3 plugin that requires JS configuration), load it explicitly with @config in src/styles/global.css:
@import "tailwindcss";
@config "../../tailwind.config.js";Refer to the official Tailwind CSS documentation for details on @theme and @config.
Create a new .astro file in the src/pages/ directory. The file path will determine the URL.
The contact page renders a deliverable form only after you configure a real endpoint. While params.contact_form_action in src/config/config.json stays at its default "#", the page shows a "not configured" notice and the submit button is disabled, so visitors cannot submit messages into the void.
To go live:
- Set
params.contact_form_actionto an endpoint that acceptsPOSTrequests β your own backend or a form service. - Add only the public address, email, and phone details you want displayed.
This theme is static and ships no mailer. Handling submissions, success messages, and error recovery is the responsibility of the endpoint you configure.
Build your site for production:
npm run buildThe static output is written to the dist/ directory, ready to deploy to any static hosting platform. Build and serve on Node.js 22.12.0 or newer, matching the prerequisites.
Run the complete local verification suite:
npm run verifyThis runs Astro type checking, unit tests, and the production build. Draft and future-dated posts are excluded from routes, search, RSS, series navigation, and homepage widgets.
Three things to configure on your host before going live:
- Root-domain or subpath hosting. Root deployments work out of the box. Subpath deployments (for example
example.com/blog/) are supported through Astro'sbasesetting β navigation, taxonomy links, pagination, favicons, RSS autodiscovery, and search are base-aware, and this is covered by a/theme/smoke build. One caveat: absolute links you write yourself inside Markdown content (for example[Blog](/blog/)) are not rewritten; prefer root-relative content links on root deployments. - Custom 404. The theme ships
src/pages/404.astro(content fromsrc/content/pages/404.md). Configure your host to serve it for unknown routes with a real 404 status;astro previewbehavior is not proof for every provider. - Cache headers. The
Cache-Controlheader the search endpoint sets on its response is not portable across CDNs; most static hosts strip response headers from flat files. Configure caching for HTML, hashed assets, and/search.jsonin your host's settings.
The theme stays lean by default: fully static pages, no client framework runtime, a system font stack for body copy plus one self-hosted variable display face for headings, syntax highlighting done at build time, responsive covers that lazy-load in cards (the article cover loads eagerly), and a click-to-load facade for YouTube embeds instead of immediate iframes.
Budget snapshot of the demo build, September 2026 (gzip estimates): shared CSS ~13 KB, and the client-side search bundle ~11 KB plus its JSON index (~33 KB for the 21-post demo β the index grows with the number and length of your posts). The search page carries that bundle and is heavier than ordinary pages. These are build-output snapshots, not Core Web Vitals results; measure your own deployment.
Repository content β posts, pages, MDX, and configuration β is a trusted build input: it runs at build time like any other code in the project. Content from an external CMS or user submissions does not share that trust and needs its own validation and ingestion boundary before it reaches a build. To report a security issue, see SECURITY.md.
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with Astro
- Styled with Tailwind CSS
- Icons from Astro Icon
- Search functionality with Fuse.js