Astro i18n blog starter

Live demo

I found that out of the box, the Astro 4.0 blog example and internationalization/localization (i18n) features require quite a bit of work to become a fully working, SEO-optimized and screen reader-friendly blog. This project attempts to make getting started a bit easier.

Requirements and goals

  • Use built-in features and reduce additional dependencies where possible. The assumption is that the Astro team will expand i18n features and that parts of this setup can be replaced with built-in functions in the future.
  • Add a minimum of styling and hard-coded settings, so you can quickly get to styling and configuring your own site.
  • Allow for multiple collections (don't abuse collections for localization)
  • Separate layouts, components and content; make sure all content is saved in markdown and data files.
  • Support the features below!

Features

  • ⛓️ Linked translations via a reference property: no need for matching slugs between locales.
  • 🏷️ Content tags Γ‘ la WordPress
  • πŸ—ΊοΈ Sitemap support with translation links
  • πŸ“‘ Localized RSS Feeds
  • 🌍 Customizable URL structure, like domain.tld/locale/directory/slug
  • πŸͺ½ Skip to content link for screen reader and keyboard users
  • πŸ‘©β€πŸ’Ό Localized author profiles from a single data file
  • πŸ” Secret/draft state to exclude posts from rendering
  • πŸ”š 404 Page not found page
  • 🐭 Ultra minimal styling without CSS classes with new.css (remove only two lines of code to remove it!)
  • πŸ”— target="_blank" for external links with Rehype plugin
  • πŸ˜‰ Separate favicon for dev server to not get confused between dev and production

Based on the official blog example, this setup still has:

  • βœ… 100/100 Lighthouse performance
  • βœ… SEO-friendly with canonical URLs and OpenGraph data
  • βœ… Markdown & MDX support

πŸš€ Project Structure

You'll see the following folders and files:

β”œβ”€β”€ public/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ content/
β”‚   β”œβ”€β”€ i18n/
β”‚   β”‚   β”œβ”€β”€ i18n.ts ← Set up locales here
β”‚   β”‚   β”œβ”€β”€ uiStrings.js ← Localized headings, labels, etc.
β”‚   β”‚   └── utilities ← i18n-specific functions
β”‚   β”œβ”€β”€ layouts/
β”‚   β”œβ”€β”€ styles/
β”‚   β”œβ”€β”€ utilities/
β”‚   β”œβ”€β”€ consts.ts ← Settings loaded by astro.config.mjs
β”‚   β”œβ”€β”€ env.d.ts
β”‚   β”œβ”€β”€ header.ts ← Settings for header menus, optionally per locale
β”‚   └── people.ts ← Bylines and author profile pages
β”œβ”€β”€ astro.config.mjs
β”œβ”€β”€ README.md
β”œβ”€β”€ package.json
└── tsconfig.json

Astro looks for .astro or .md files in the src/pages/ directory. Each page is exposed as a route based on its file name.

There's nothing special about src/components/, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.

The src/content/ directory contains collections of related markdown and MDX documents. A 'blog' collection has been defined already.

Any static assets, like images, can be placed in the public/ directory.

🧞 Commands

All default commands can be run from the root of the project, from a terminal:

Command Action
pnpm install Installs dependencies
pnpm run dev Starts local dev server at localhost:4321
pnpm run build Build your production site to ./dist/
pnpm run preview Preview your build locally, before deploying
pnpm run astro ... Run CLI commands like astro add, astro check
pnpm run astro -- --help Get help using the Astro CLI

To do

  • Get feedback. This is my third Astro project, but it's I noticed while making this, that I'm very much a novice Astro user. Feel free to contact me and make pull requests.
  • Although there are no errors or known issues, your editor may show a few squiggly lines caused missing/faulty TypeScript settings.