feat!: AstroPaper v6 (#631)

* feat: add initial configuration and social icons for AstroPaper theme

* feat: add theme styles and design tokens

* chore: configure Astro with sitemap, i18n, fonts, and tooling

- Set site URL, i18n (single locale, no prefix), sitemap integration
- Add Google Sans Code font via stable fonts API
- Configure Shiki dual-theme markdown (min-light / night-owl)
- Fix astro-paper.config.ts to use relative import (alias not
  available when Vite loads root-level config files)
- Add @astrojs/sitemap and @typescript-eslint/parser dependencies
- Wire @typescript-eslint/parser into ESLint so TypeScript syntax
  in Astro frontmatter (type Props, etc.) parses correctly

* feat: add base styles, dark variant, and typography

- global.css: dark variant via [data-theme], base layer for * / a /
  button selectors, scrollbar tokens, layout utilities (max-w-app,
  app-layout), active-nav as @utility for Tailwind variant support
- html and body classes moved directly onto elements in BaseLayout
  (Tailwind-native approach) so only truly global selectors remain here
- typography.css: prose overrides, Shiki light/dark code block
  switching, diff/highlight/word-highlight transformer styles

* feat: add i18n types, English strings, and useTranslations helper

Plain typed object approach — no third-party i18n library needed.
Paraglide.js was considered but requires SSR output (hard blocker
for a static Astro site).

- UIStrings interface with nav, post, pagination, and a11y groups
- en.ts with `satisfies UIStrings` for literal-type preservation
- useTranslations(locale) helper falls back to English automatically

Adding a new language is a one-file addition; full routing stays
as a registry add-on.

* feat: add client-side theme toggle script

- Reads window.__theme.value set by the inline FOUC-prevention script
  to avoid re-detecting the theme on first load
- Toggles data-theme on <html> and persists to localStorage
- Fills <meta name="theme-color"> with the computed background colour
  so Android's browser chrome matches the page
- Re-runs setup on astro:after-swap for View Transitions navigation
- Carries theme-color across astro:before-swap to prevent navbar
  flicker on Android during page transitions
- Syncs with OS prefers-color-scheme changes at runtime

* feat: add BaseLayout and PostLayout

BaseLayout (replaces scaffold Layout.astro):
- Font, canonical URL via Astro.site, RSS autodiscovery
- FOUC-prevention inline script sets data-theme before first paint
  and exposes window.__theme.value for theme.ts to reuse
- html/body classes on elements directly (Tailwind-native)
- <slot name="head"> for child layout injection
- ClientRouter for View Transitions (respects lightAndDarkMode flag)
- googleVerification rendered from config instead of .env — it is a
  public string, not a secret, and not environment-specific

PostLayout (new):
- Wraps BaseLayout; injects article-specific head content via slot
- Overrides og:type to "article"
- Adds article:published_time / article:modified_time conditionally
- JSON-LD BlogPosting with conditional datePublished/dateModified
  (fixes old bug where absent dates produced "undefined" string)
- Structured data only on actual post pages (not home/archives/tags)

SiteConfig: add optional googleVerification field

* chore: replace scaffold index page with BaseLayout placeholder

* feat: add Header component

* feat: add Footer and Socials component

* chore: install dayjs, slugify, zod, @astrojs/mdx and add MDX integration

* feat: add resolved config that applies defaults in one place

Defaults for posts, features, socials, and shareLinks are merged in
src/config.ts so all consuming code gets non-optional types with no
scattered ?? fallbacks.

* feat: add content schema, blog path, and post utilities

Renames collection blog→posts, moves content to src/content/posts/,
adds .mdx support, and adds a typed pages collection. Includes
getSortedPosts, postFilter, getPath, and slugify utilities.

* feat: add Datetime and Card components

* refactor: switch layouts and components to resolved config

Replaces @/astro-paper.config imports with @/config and removes
optional chaining on feature flags now that the resolved config
guarantees non-optional values.

* feat: add home and footer i18n strings

* feat: implement home page with hero, featured, and recent posts

Replaces the BaseLayout placeholder with the full index page:
hero section with RSS link and social links, featured posts section,
recent posts capped at posts.perIndex, and an All Posts link. All
section labels come from i18n.

* feat: add pagination component

* feat: add Breadcrumb component with locale support

* feat: add Main component

* refactor: update code formatting in Card.astro

* feat: add posts page

* fix: add missing @astrojs/mdx dependency

* refactor: rename meta to pages in i18n

* refactor: improve code formatting in Breadcrumb

* refactor: destructure props in Main component for clarity

* feat: add tag pages

* feat: add About page

* chore: update i18n configuration to use site language from config

* feat: add Archives page

* feat: integrate Pagefind search functionality

* feat: add dynamic Open Graph image generation for posts

* feat: add post detail page

* feat: add Shiki transformers

* chore: remove unused edit link text

* chore: update .gitignore to include generated Pagefind directory

* chore: update site URL in configuration to production link

* chore: replace favicon and remove unused SVG assets, add new Open Graph image

* feat: update site config with default values

* feat: add default OG image path resolution

* fix: ensure edit post feature checks for enabled status correctly

* feat: implement dynamic Open Graph image generation

* feat: add RSS feed generation functionality

* feat: add 404 Not Found page

* feat: add robots.txt generation for SEO optimization

* refactor: change getSortedPosts to a named export

* refactor: change postFilter to a named export

* refactor: rename BaseLayout to Layout

* refactor: standardize locale handling across components

* refactor: update getPostsByGroupCondition location

* chore: remove unused Welcome component

* refactor(i18n): update links using getRelativeLocaleUrl

* refactor(i18n): add dynamic locale loading

* fix: update language attribute to use current locale

* fix: correct wording for updatedAt in post translations

* fix: update layout titles to use correct translation keys for tags pages

* chore: use new colors for better DX and a11y

* feat: add underline icon for active icon nav

* feat: add toc for markdown contents

* refactor: remove unused feature flags in config

* refactor(i18n): enhance locale handling and path management

* fix: ts unused variable hint

* refactor: extract locale stripping logic into a util func

* refactor(i18n): improve locale handling in tag pages

* refactor: update post URL helper functions

* refactor(i18n): replace pathWithBase with getRelativeLocaleUrl for locale handling

* refactor: rename fileWithBase to getAssetPath

* refactor: use runtime agnostic APIs for file paths

* refactor: use transition directive for heading transition

* refactor: remove unused title element from tag page

* fix: decouple ClientRouter from lightAndDarkMode flag

* refactor: rename `postPaths.ts` to `getPostPaths.ts`

* refactor: remove unused `minutesRead` string from post translations

* refactor: simplify AdjacentPostNav component by passing prevPost and nextPost directly

* refactor: remove unused code declaration

* docs: add existing blog posts

* chore: update astro and @astrojs/check dependencies to latest versions

* build: use experimental svg optimizer

* chore(repo): restore project meta files and Docker configs

* refactor: update code formatting with Prettier

* docs: update README and docs

* docs: add JSDoc comments to utility functions

* docs: add JSDoc comments to resolved config file

* fix(og): avoid double slashes when appending index.png

* chore(ci): update Node.js version to 22.12.0 in CI workflow

* feat: improve og image generation with Astro's getFontFileURL API (#632)

* feat: improve og image generation with Astro's getFontFileURL API

- remove @resvg/resvg-js and use sharp to convert SVG to PNG
- update og image generation to use Astro's getFontFileURL API for better font handling

* docs: update README and dynamic OG images documentation

- remove outdated content and clarify dynamic OG image generation process in README.
- add new image example and update instructions for handling non-Latin characters in dynamic OG images.
- adjust copyright year in README to 2026.

* fix(header): adjust icon button alignment in mobile

* feat(docs): add ResponsiveTable to use it in MDX posts (#634)

* feat(docs): add ResponsiveTable to use it in MDX posts

Introduce ResponsiveTable with variant-based styling. Rename docs posts to
.mdx, wrap tables in the component, and remove redundant table `code` rules
from prose typography.

* chore(prettier): ignore .mdx files when checking format

* chore(ci): update Node.js version to 24 in CI workflow

* bump: upgrade Astro and dependencies

* fix: remove redundant backUrl script bug

* fix(header): adjust button and icon alignment

* fix(a11y): improve muted-foreground color contrast

* docs: update predefined color schemes

* chore: support site verification env as fallback for googleVerification

* docs: add astro paper v6 updates in docs

* docs: add AstroPaper-v6.png in astro-paper-6 blog post

* fix: update back-to-top button DOM placement (#641)

Closes #626, #131, #493
This commit is contained in:
Sat Naing
2026-05-17 16:17:58 +07:00
committed by GitHub
parent f3005328e5
commit f0b644de3a
122 changed files with 5387 additions and 4561 deletions
+44 -58
View File
@@ -1,6 +1,6 @@
# AstroPaper 📄
![AstroPaper](public/astropaper-og.jpg)
![AstroPaper](public/default-og.jpg)
[![Figma](https://img.shields.io/badge/Figma-F24E1E?style=for-the-badge&logo=figma&logoColor=white)](https://www.figma.com/community/file/1356898632249991861)
![Typescript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white)
![GitHub](https://img.shields.io/github/license/satnaing/astro-paper?color=%232F3741&style=for-the-badge)
@@ -19,12 +19,15 @@ Read [the blog posts](https://astro-paper.pages.dev/posts/) or check [the README
- [x] responsive (mobile ~ desktops)
- [x] SEO-friendly
- [x] light & dark mode
- [x] fuzzy search
- [x] static search ([Pagefind](https://pagefind.app/))
- [x] draft posts & pagination
- [x] sitemap & rss feed
- [x] MDX support
- [x] collapsible table of contents
- [x] followed best practices
- [x] highly customizable
- [x] dynamic OG image generation for blog posts [#15](https://github.com/satnaing/astro-paper/pull/15) ([Blog Post](https://astro-paper.pages.dev/posts/dynamic-og-image-generation-in-astropaper-blog-posts/))
- [x] dynamic OG image generation for blog posts ([Blog Post](https://astro-paper.pages.dev/posts/dynamic-og-image-generation-in-astropaper-blog-posts/))
- [x] i18n ready
_Note: I've tested screen-reader accessibility of AstroPaper using **VoiceOver** on Mac and **TalkBack** on Android. I couldn't test all other screen-readers out there. However, accessibility enhancements in AstroPaper should be working fine on others as well._
@@ -43,44 +46,42 @@ Inside of AstroPaper, you'll see the following folders and files:
```bash
/
├── public/
│ ├── pagefind/ # auto-generated when build
│ ├── pagefind/ # auto-generated on build
│ ├── favicon.svg
│ └── astropaper-og.jpg
│ └── default-og.jpg
├── src/
│ ├── assets/
│ │ ├── icons/
│ │ └── images/
│ ├── components/
│ ├── data/
│ │ ── blog/
│ ├── content/
│ │ ── pages/
│ │ │ └── about.md
│ │ └── posts/
│ │ └── some-blog-posts.md
│ ├── i18n/
│ ├── layouts/
│ ├── pages/
│ ├── scripts/
│ ├── styles/
│ ├── types/
│ ├── utils/
│ ├── config.ts
── constants.ts
│ ├── content.config.ts
│ ├── env.d.ts
│ └── remark-collapse.d.ts
── content.config.ts
├── astro-paper.config.ts # user-defined configurations
└── astro.config.ts
```
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
Any static assets, like images, can be placed in the `public/` directory.
All blog posts are stored in `src/data/blog` directory.
All blog posts are stored in the `src/content/posts/` directory. You can organise posts into subdirectories — the subdirectory name becomes part of the post URL.
## 📖 Documentation
Documentation can be read in two formats\_ _markdown_ & _blog post_.
- Configuration - [markdown](src/data/blog/how-to-configure-astropaper-theme.md) | [blog post](https://astro-paper.pages.dev/posts/how-to-configure-astropaper-theme/)
- Add Posts - [markdown](src/data/blog/adding-new-post.md) | [blog post](https://astro-paper.pages.dev/posts/adding-new-posts-in-astropaper-theme/)
- Customize Color Schemes - [markdown](src/data/blog/customizing-astropaper-theme-color-schemes.md) | [blog post](https://astro-paper.pages.dev/posts/customizing-astropaper-theme-color-schemes/)
- Predefined Color Schemes - [markdown](src/data/blog/predefined-color-schemes.md) | [blog post](https://astro-paper.pages.dev/posts/predefined-color-schemes/)
- Configuration - [markdown](src/content/posts/how-to-configure-astropaper-theme.md) | [blog post](https://astro-paper.pages.dev/posts/how-to-configure-astropaper-theme/)
- Add Posts - [markdown](src/content/posts/adding-new-post.md) | [blog post](https://astro-paper.pages.dev/posts/adding-new-posts-in-astropaper-theme/)
- Customize Color Schemes - [markdown](src/content/posts/customizing-astropaper-theme-color-schemes.md) | [blog post](https://astro-paper.pages.dev/posts/customizing-astropaper-theme-color-schemes/)
- Predefined Color Schemes - [markdown](src/content/posts/predefined-color-schemes.md) | [blog post](https://astro-paper.pages.dev/posts/predefined-color-schemes/)
## 💻 Tech Stack
@@ -88,12 +89,12 @@ Documentation can be read in two formats\_ _markdown_ & _blog post_.
**Type Checking** - [TypeScript](https://www.typescriptlang.org/)
**Styling** - [TailwindCSS](https://tailwindcss.com/)
**UI/UX** - [Figma Design File](https://www.figma.com/community/file/1356898632249991861)
**Static Search** - [FuseJS](https://pagefind.app/)
**Static Search** - [Pagefind](https://pagefind.app/)
**Icons** - [Tablers](https://tabler-icons.io/)
**Code Formatting** - [Prettier](https://prettier.io/)
**Deployment** - [Cloudflare Pages](https://pages.cloudflare.com/)
**Illustration in About Page** - [https://freesvgillustration.com](https://freesvgillustration.com/)
**Linting** - [ESLint](https://eslint.org)
**Linting** - [ESLint](https://eslint.org)
**Dynamic OG images** - [Satori](https://github.com/vercel/satori) + [Sharp](https://sharp.pixelplumbing.com/) + [Astro Fonts](https://docs.astro.build/en/guides/fonts/)
## 👨🏻‍💻 Running Locally
@@ -120,26 +121,21 @@ Then start the project by running the following commands:
pnpm install
# start running the project
pnpm run dev
```
As an alternative approach, if you have Docker installed, you can use Docker to run this project locally. Here's how:
```bash
# Build the Docker image
docker build -t astropaper .
# Run the Docker container
docker run -p 4321:80 astropaper
pnpm dev
```
## Google Site Verification (optional)
You can easily add your [Google Site Verification HTML tag](https://support.google.com/webmasters/answer/9008080#meta_tag_verification&zippy=%2Chtml-tag) in AstroPaper using an environment variable. This step is optional. If you don't add the following environment variable, the google-site-verification tag won't appear in the HTML `<head>` section.
You can add your [Google Site Verification HTML tag](https://support.google.com/webmasters/answer/9008080#meta_tag_verification&zippy=%2Chtml-tag) by setting `site.googleVerification` in `astro-paper.config.ts`:
```bash
# in your environment variable file (.env)
PUBLIC_GOOGLE_SITE_VERIFICATION=your-google-site-verification-value
```ts file="astro-paper.config.ts"
export default defineAstroPaperConfig({
site: {
// ...
googleVerification: "your-google-site-verification-value",
},
// ...
});
```
> See [this discussion](https://github.com/satnaing/astro-paper/discussions/334#discussioncomment-10139247) for adding AstroPaper to the Google Search Console.
@@ -148,32 +144,22 @@ PUBLIC_GOOGLE_SITE_VERIFICATION=your-google-site-verification-value
All commands are run from the root of the project, from a terminal:
> **_Note!_** For `Docker` commands we must have it [installed](https://docs.docker.com/engine/install/) in your machine.
| 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 format:check` | Check code format with Prettier |
| `pnpm run format` | Format codes with Prettier |
| `pnpm run sync` | Generates TypeScript types for all Astro modules. [Learn more](https://docs.astro.build/en/reference/cli-reference/#astro-sync). |
| `pnpm run lint` | Lint with ESLint |
| `docker compose up -d` | Run AstroPaper on docker, You can access with the same hostname and port informed on `dev` command. |
| `docker compose run app npm install` | You can run any command above into the docker container. |
| `docker build -t astropaper .` | Build Docker image for AstroPaper. |
| `docker run -p 4321:80 astropaper` | Run AstroPaper on Docker. The website will be accessible at `http://localhost:4321`. |
> **_Warning!_** Windows PowerShell users may need to install the [concurrently package](https://www.npmjs.com/package/concurrently) if they want to [run diagnostics](https://docs.astro.build/en/reference/cli-reference/#astro-check) during development (`astro check --watch & astro dev`). For more info, see [this issue](https://github.com/satnaing/astro-paper/issues/113).
| Command | Action |
| :--------------- | :------------------------------------------------------------------------------------------------------------------------------- |
| `pnpm install` | Installs dependencies |
| `pnpm dev` | Starts local dev server at `localhost:4321` |
| `pnpm build` | Type-checks, builds the site, runs Pagefind indexing, and copies the index to `public/pagefind/` |
| `pnpm preview` | Preview your build locally, before deploying |
| `pnpm sync` | Generates TypeScript types for all Astro modules. [Learn more](https://docs.astro.build/en/reference/cli-reference/#astro-sync). |
| `pnpm astro ...` | Run CLI commands like `astro add`, `astro check` |
## ✨ Feedback & Suggestions
If you have any suggestions/feedback, you can contact me via [my email](mailto:contact@satnaing.dev). Alternatively, feel free to open an issue if you find bugs or want to request new features.
If you have any suggestions/feedback, you can contact me via [my email](mailto:satnaingdev+astropaper@gmail.com). Alternatively, feel free to open an issue if you find bugs or want to request new features.
## 📜 License
Licensed under the MIT License, Copyright © 2025
Licensed under the MIT License, Copyright © 2026
---