Heavily customized version of the AstroPaper theme with a new aesthetic, image galleries, global search modal, and dozens of visual and interactive improvements.
🌐 Live demo: devosfera.vercel.app
Note: This project is primarily my personal blog. If anyone wishes to use it, feel free to delete all entries and edit the settings freely.
- Features
- Project structure
- Installation and local development
- Commands
- Creating content
- GalleryEmbed component
- Configuration
- Upstream issues resolved
- License
- Type-safe Markdown, good performance, accessible and responsive
- Full SEO (meta tags, Open Graph, sitemap, RSS), light/dark mode
- Dynamically generated OG images with Satori
- Hero with animated prompt configurable from
heroTerminalPromptinsrc/config.ts(default:~/ready-to-go $) - Global backdrop: grid + cursor glow + noise texture (all pages) optional and configurable from
src/config.ts - Glassmorphism on navbar, cards and modals
| Role | Font |
|---|---|
| Body | Wotfard (local) |
| Code / Mono | Cascadia Code (local) |
| Italics / H3 | Sriracha (Local) |
- Modal via
⌘K/Ctrl+Kpowered by Pagefind (static index) and full keyboard navigation (if you want to test it locally, runpnpm run buildfirst and after thatpnpm run devorpnpm run previewsince the index is only generated in production)
- Albums in
src/data/galleries/<slug>/; images optimized at build-time (srcset, WebP, lazy) - Native lightbox with
<dialog>, redesigned fullscreen layout, keyboard navigation and edge-aware prev/next controls <GalleryEmbed>to embed galleries inside MDX posts without importing- Controlled by
showGalleriesinsrc/config.ts(also gates gallery inclusion in mixed feeds) — see GALLERIES.md
- Optional mixed feed controlled by
showGalleriesInIndexinsrc/config.ts(effective only ifshowGalleriesistrue) - When both flags are enabled, gallery entries are included in
/,/posts,/archives,/tags, and/rss.xml - Shared URL/date helpers keep routing and publish-date sorting consistent across all listing pages
- Gallery entries include a visual badge in cards and archive timeline items
- Parallel collection loading in key routes using
Promise.all - Optimized sorting and tag extraction logic for larger content sets
- Stronger shared typing across blog/gallery entries (removed weak
anyusage) - Reduced duplicated route/slug logic by centralizing entry helpers
- Intro audio player in the hero with terminal aesthetic (wave bars, progress bar)
- Fully togglable and configurable from
src/config.ts
| Page | Highlights |
|---|---|
/ Home |
Terminal hero, featured grid, section counters, optional mixed feed |
/archives |
Vertical timeline with glow, includes gallery entries |
/tags |
Grid with proportional progress bar |
/search |
Reactive aurora, restyled Pagefind |
| Posts | Paginated mixed feed (posts + galleries), inline Pagefind search |
/
├── public/
│ ├── audio/ # Audio files (intro, etc.)
│ └── pagefind/ # Search index (generated at build)
├── src/
│ ├── assets/ # Local fonts, SVG icons and logo
│ ├── components/ # Reusable Astro components
│ ├── data/
│ │ ├── blog/ # Posts .md / .mdx
│ │ └── galleries/ # Galleries (one folder per album)
│ ├── layouts/ # Root layout, PostDetails, etc.
│ ├── pages/ # Astro routes
│ ├── styles/ # global.css, typography.css
│ └── utils/ # Filters, OG with Satori, Shiki transformers
└── astro.config.ts
Requirements: Node.js 20+ and pnpm.
# 1. Install dependencies
pnpm install
# 2. Development server
pnpm run dev
# → http://localhost:4321The Pagefind search index is only available in the production build. To test it locally:
pnpm run build && pnpm run preview/devdocker build -t devosfera-blog .
docker run -p 4321:80 devosfera-blog| Command | Action |
|---|---|
pnpm install |
Install dependencies |
pnpm run dev |
Local dev server at localhost:4321 |
pnpm run build |
Production build (astro check + build + Pagefind) |
pnpm run preview |
Preview the production build |
pnpm run format |
Format with Prettier |
pnpm run lint |
Lint with ESLint |
pnpm run buildinternally runspagefind --site dist && cp -r dist/pagefind public/. The search index ends up inpublic/pagefind/ready for preview.
Create a .md or .mdx file with the following frontmatter:
---
title: "Post title"
pubDatetime: 2026-01-15T10:00:00Z # required — ISO 8601 with timezone
description: "Short description for SEO and cards"
tags: ["astro", "dev"]
featured: false # highlight on the home page
draft: false # hidden in production
timezone: "America/Guatemala" # overrides SITE.timezone
hideEditPost: false
---MDX: JSX components can be used directly. <GalleryEmbed> is available without importing it (see next section).
Table of Contents: add ## Table of contents to the post body to auto-generate the TOC with remark-toc + remark-collapse.
Annotated code blocks (via Shiki transformers):
// [!code highlight] → highlight the line
// [!code ++] → added line (diff)
// [!code --] → removed line (diff)
// fileName: file.ts → display the filename above the block
Quick setup:
- Create a folder in
src/data/galleries/<slug>/. - Add
index.md(gallery metadata) and image files. - Use numeric prefixes (
01-,02-, …) if you want to control image order. - The folder slug becomes the route:
/galleries/<slug>.
For full details (frontmatter fields, cover behavior, alt generation, and image optimization), see GALLERIES.md.
Embed a gallery inside any .mdx post — no import needed:
<GalleryEmbed slug="my-trip-to-tokyo" />Optional props: limit (0 = all), cols (2 | 3 | 4), showLink (true/false).
For advanced usage, full props reference, lightbox behavior, and invalid slug fallback, see GALLERIES.md.
All site configuration lives in src/config.ts (the SITE constant). It includes general settings (title, description, timezone), feature toggles (galleries, audio player, mixed feed), and content limits (posts per page, gallery embed limit).
Social links and "Share" links are defined in src/constants.ts.
For details on visual effects, typography and the design system see CUSTOMIZATIONS.md.
Bugs and feature requests from the official AstroPaper repository implemented in this version:
| Issue | Description | Files | Credits |
|---|---|---|---|
| #614 | Back to Top shifts the pagination button when ShareLinks is empty |
BackToTopButton.astro |
— |
| #574 | Markdown tables overflow the layout on mobile — fixed with w-full table-auto and word-wrap on cells |
typography.css |
@GladerJ — solution |
| #569 | Back to Top inconsistent on desktop — unified circular design with progress ring and fixed positioning |
BackToTopButton.astro, PostDetails.astro |
— |
| #566 | Share links don't open in a new tab — added target="_blank" and rel="noopener noreferrer" |
ShareLinks.astro |
PR #611 by @zerone0x |
| #131 | No MDX support — added @astrojs/mdx integration with extendMarkdownConfig: true |
astro.config.ts, content.config.ts |
— |
| #495 | Inconsistent post filtering by timezone — fixed using dayjs + utc/timezone plugins; also fixed a bug in the reference solution that used .millisecond() instead of .valueOf() |
postFilter.ts |
@kj-9 — reference fix |
| #553 | No galleries section — implemented full /galleries section with lightbox, GalleryEmbed, image optimization and showGalleries flag. See GALLERIES.md |
multiple — see GALLERIES.md | — |
Based on AstroPaper by Sat Naing, licensed under MIT. Customizations © 0xdres.
