Base du site

This commit is contained in:
Gu://em_ 2025-05-28 04:04:47 +02:00
parent 3dfd6a646d
commit 88c2d693b4
40 changed files with 167 additions and 3071 deletions

175
README.md
View file

@ -1,177 +1,10 @@
# AstroPaper 📄
# Oblog parallels
![AstroPaper](public/astropaper-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)
[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits&logoColor=white&style=for-the-badge)](https://conventionalcommits.org)
[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=for-the-badge)](http://commitizen.github.io/cz-cli/)
Simplement le code source de mon blog.
AstroPaper is a minimal, responsive, accessible and SEO-friendly Astro blog theme. This theme is designed and crafted based on [my personal blog](https://satnaing.dev/blog).
Une version légèrement modifiée du thème AstroPaper pour Astro.
Read [the blog posts](https://astro-paper.pages.dev/posts/) or check [the README Documentation Section](#-documentation) for more info.
## 🔥 Features
- [x] type-safe markdown
- [x] super fast performance
- [x] accessible (Keyboard/VoiceOver)
- [x] responsive (mobile ~ desktops)
- [x] SEO-friendly
- [x] light & dark mode
- [x] fuzzy search
- [x] draft posts & pagination
- [x] sitemap & rss feed
- [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/))
_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._
## ✅ Lighthouse Score
<p align="center">
<a href="https://pagespeed.web.dev/report?url=https%3A%2F%2Fastro-paper.pages.dev%2F&form_factor=desktop">
<img width="710" alt="AstroPaper Lighthouse Score" src="AstroPaper-lighthouse-score.svg">
<a>
</p>
## 🚀 Project Structure
Inside of AstroPaper, you'll see the following folders and files:
```bash
/
├── public/
│ ├── assets/
| ├── pagefind/ # auto-generated when build
│ └── favicon.svg
│ └── astropaper-og.jpg
│ └── favicon.svg
│ └── toggle-theme.js
├── src/
│ ├── assets/
│ │ └── icons/
│ │ └── images/
│ ├── components/
│ ├── data/
│ │ └── blog/
│ │ └── some-blog-posts.md
│ ├── layouts/
│ └── pages/
│ └── styles/
│ └── utils/
│ └── config.ts
│ └── constants.ts
│ └── content.config.ts
└── 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.
## 📖 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/)
## 💻 Tech Stack
**Main Framework** - [Astro](https://astro.build/)
**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/)
**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)
## 👨🏻‍💻 Running Locally
You can start using this project locally by running the following command in your desired directory:
```bash
# pnpm
pnpm create astro@latest --template satnaing/astro-paper
# pnpm
pnpm create astro@latest -- --template satnaing/astro-paper
# yarn
yarn create astro --template satnaing/astro-paper
```
Then start the project by running the following commands:
```bash
# install dependencies if you haven't done so in the previous step.
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
```
## 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.
```bash
# in your environment variable file (.env)
PUBLIC_GOOGLE_SITE_VERIFICATION=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.
## 🧞 Commands
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 pnpm 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).
## ✨ 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.
## 📜 License
Licensed under the MIT License, Copyright © 2025
---
Made with 🤍 by [Sat Naing](https://satnaing.dev) 👨🏻‍💻 and [contributors](https://github.com/satnaing/astro-paper/graphs/contributors).
Voilà.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

BIN
public/assets/menage.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

View file

@ -1,361 +0,0 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="865.76" height="682.89" viewBox="0 0 865.76 682.89">
<defs>
<style xmlns="http://www.w3.org/1999/xhtml">*, body, html { -webkit-font-smoothing: antialiased; }
img, svg { max-width: 100%; }
</style>
</defs>
<path d="M391.82,532.2c-15.44,2.82-87.85,18.09-73.28,55a33.24,33.24,0,0,0,9.74,13.13c18.18,15.25,83.33,52.58,272.06,32.22,10.69-1.15,21.42-1.86,32.17-2.06,49.73-.92,206-9.34,202-78.54,0,0-2.07-38.74-95.7-26.87l-71.21-4.43s-160.55-12.38-268.7,10.11C396.57,531.29,394.2,531.77,391.82,532.2Z" fill="#787878" data-primary="true"/>
<path d="M391.82,532.2c-15.44,2.82-87.85,18.09-73.28,55a33.24,33.24,0,0,0,9.74,13.13c18.18,15.25,83.33,52.58,272.06,32.22,10.69-1.15,21.42-1.86,32.17-2.06,49.73-.92,206-9.34,202-78.54,0,0-2.07-38.74-95.7-26.87l-71.21-4.43s-160.55-12.38-268.7,10.11C396.57,531.29,394.2,531.77,391.82,532.2Z" fill="#fff" opacity="0.7"/>
<path d="M503.08,522.3C179.26,552.79,133.91,359.63,133.91,359.63c-24.79-67.13-3.45-111,27.66-152.68a303.36,303.36,0,0,1,117.77-94.5c74.9-34.06,126.36-41,126.36-41S622.58,15.68,735.64,183.7c0,0,108,135.55,37.54,221.14,0,0-35.14,47.34-127.63,82.89l-69.3,20.46A387.7,387.7,0,0,1,503.08,522.3Z" fill="#787878" data-primary="true"/>
<path d="M503.08,522.3C179.26,552.79,133.91,359.63,133.91,359.63c-24.79-67.13-3.45-111,27.66-152.68a303.36,303.36,0,0,1,117.77-94.5c74.9-34.06,126.36-41,126.36-41S622.58,15.68,735.64,183.7c0,0,108,135.55,37.54,221.14,0,0-35.14,47.34-127.63,82.89l-69.3,20.46A387.7,387.7,0,0,1,503.08,522.3Z" fill="#fff" opacity="0.7"/>
<rect x="104.67" y="206.46" width="463.2" height="348.88" fill="#fff"/>
<rect x="108.43" y="206.46" width="459.44" height="35.42" fill="#e6e6e6"/>
<rect x="128.82" y="259.06" width="104.13" height="104.13" fill="#787878" opacity="0.29" data-primary="true"/>
<rect x="713.86" y="369.62" width="5.37" height="37.57" fill="#999"/>
<polygon points="664.89 442.18 664.89 554.44 672.53 554.44 676.93 436.58 664.89 442.18" fill="#ccc"/>
<polygon points="711.71 420.08 711.71 537.08 719.36 537.08 723.52 414.71 711.71 420.08" fill="#ccc"/>
<polygon points="668.23 434.1 733.18 405.05 703.86 399.96 670.01 385.44 668.23 434.1" fill="#ccc"/>
<path d="M656.14,446.25l77-35.83v-5.37L668.23,434.1S660.68,442.36,656.14,446.25Z" fill="#b3b3b3"/>
<path d="M693.46,271.94H734a4.55,4.55,0,0,1,4.55,4.55v67.37a0,0,0,0,1,0,0H693.46a0,0,0,0,1,0,0V271.94A0,0,0,0,1,693.46,271.94Z" fill="#999"/>
<rect x="241.54" y="44.36" width="325.8" height="139.55" fill="#787878" data-primary="true"/>
<rect x="263.01" y="83.01" width="100.91" height="65.48" fill="#fff" opacity="0.3"/>
<g opacity="0.3">
<path d="M297.36,131.59a1.07,1.07,0,0,1-.76-.32l-14.79-14.76a1.08,1.08,0,0,1,0-1.5l14.79-15.56a1.07,1.07,0,0,1,1.56,1.47l-14.07,14.81,14.05,14a1.07,1.07,0,0,1,0,1.52A1.09,1.09,0,0,1,297.36,131.59Z" fill="#fff"/>
</g>
<g opacity="0.3">
<path d="M328.73,132.66a1.06,1.06,0,0,1-.76-.31,1.07,1.07,0,0,1,0-1.52l14-14L328,102a1.08,1.08,0,1,1,1.56-1.48l14.78,15.56a1.06,1.06,0,0,1,0,1.5l-14.78,14.77A1.07,1.07,0,0,1,328.73,132.66Z" fill="#fff"/>
</g>
<g opacity="0.3">
<path d="M305.56,131.59a1.08,1.08,0,0,1-1-1.56l14.34-28.18a1.08,1.08,0,1,1,1.92,1L306.51,131A1.07,1.07,0,0,1,305.56,131.59Z" fill="#fff"/>
</g>
<path d="M524.39,119.51H454.62a1.08,1.08,0,0,1,0-2.15h69.77a1.08,1.08,0,1,1,0,2.15Z" fill="#fff"/>
<path d="M540.5,132.39H454.62a1.08,1.08,0,0,1,0-2.15H540.5a1.08,1.08,0,0,1,0,2.15Z" fill="#fff"/>
<rect x="460.52" y="153.86" width="65.48" height="16.1" rx="7.5" fill="#fff" opacity="0.3"/>
<path d="M567.33,44.36V183.91H241.54s54.75-59.1,144.51-74c4.1-.68,8.24-1.12,12.38-1.4C426.41,106.6,557.79,95.18,567.33,44.36Z" fill="#fff" opacity="0.3"/>
<rect x="31.14" y="128.09" width="187.86" height="213.62" fill="#787878" data-primary="true"/>
<rect x="31.14" y="128.09" width="187.86" height="34.35" fill="#fff" opacity="0.3"/>
<rect x="46.17" y="173.18" width="57.97" height="57.97" fill="#282728" data-secondary="true"/>
<circle cx="164.78" cy="145.27" r="3.76" fill="#fff" opacity="0.3"/>
<circle cx="184.11" cy="145.27" r="3.76" fill="#fff" opacity="0.3"/>
<circle cx="203.43" cy="145.27" r="3.76" fill="#fff" opacity="0.3"/>
<path d="M170.69,192.5H117a1.07,1.07,0,1,1,0-2.14h53.67a1.07,1.07,0,0,1,0,2.14Z" fill="#fff"/>
<path d="M186.25,205.38h-68.7a1.07,1.07,0,0,1,0-2.14h68.7a1.07,1.07,0,1,1,0,2.14Z" fill="#fff"/>
<path d="M203.43,218.27H117.55a1.08,1.08,0,0,1,0-2.15h85.88a1.08,1.08,0,0,1,0,2.15Z" fill="#fff"/>
<path d="M168,287H84.28a1.08,1.08,0,1,1,0-2.15H168a1.08,1.08,0,0,1,0,2.15Z" fill="#fff"/>
<path d="M194.84,299.85H57.44a1.08,1.08,0,1,1,0-2.15h137.4a1.08,1.08,0,1,1,0,2.15Z" fill="#fff"/>
<path d="M168.54,312.73H83.74a1.08,1.08,0,1,1,0-2.15h84.8a1.08,1.08,0,1,1,0,2.15Z" fill="#fff"/>
<rect x="83.74" y="248.32" width="78.36" height="16.1" fill="#fff" opacity="0.3"/>
<rect x="256.57" y="259.06" width="66.55" height="17.18" fill="#787878" opacity="0.29" data-primary="true"/>
<path d="M308.78,293.79H256.57a1.08,1.08,0,1,1,0-2.15h52.21a1.08,1.08,0,1,1,0,2.15Z" fill="#e6e6e6"/>
<path d="M325.8,306.67H256.57a1.07,1.07,0,1,1,0-2.14H325.8a1.07,1.07,0,1,1,0,2.14Z" fill="#e6e6e6"/>
<path d="M339.76,319.55H256.57a1.07,1.07,0,1,1,0-2.14h83.19a1.07,1.07,0,0,1,0,2.14Z" fill="#e6e6e6"/>
<path d="M379.48,332.44H256.57a1.08,1.08,0,1,1,0-2.15H379.48a1.08,1.08,0,0,1,0,2.15Z" fill="#e6e6e6"/>
<rect x="256.57" y="348.15" width="154.58" height="15.03" fill="#787878" opacity="0.29" data-primary="true"/>
<path d="M252.45,400.29h-122a1.08,1.08,0,0,1,0-2.15h122a1.08,1.08,0,1,1,0,2.15Z" fill="#e6e6e6"/>
<path d="M353.18,400.29H268.91a1.08,1.08,0,0,1,0-2.15h84.27a1.08,1.08,0,0,1,0,2.15Z" fill="#e6e6e6"/>
<path d="M417.59,400.29H388.06a1.08,1.08,0,0,1,0-2.15h29.53a1.08,1.08,0,0,1,0,2.15Z" fill="#e6e6e6"/>
<rect x="256.57" y="396.53" width="5.37" height="5.37" fill="#787878" opacity="0.29" data-primary="true"/>
<rect x="360.69" y="396.53" width="5.37" height="5.37" fill="#787878" opacity="0.29" data-primary="true"/>
<rect x="373.57" y="396.53" width="5.37" height="5.37" fill="#ccc"/>
<path d="M223.29,429.16H131a1.08,1.08,0,0,1,0-2.15h92.32a1.08,1.08,0,0,1,0,2.15Z" fill="#e6e6e6"/>
<path d="M289.84,455.37H129.9a1.08,1.08,0,1,1,0-2.15H289.84a1.08,1.08,0,1,1,0,2.15Z" fill="#e6e6e6"/>
<path d="M325.27,429.16H255a1.08,1.08,0,1,1,0-2.15h70.31a1.08,1.08,0,0,1,0,2.15Z" fill="#e6e6e6"/>
<path d="M349.42,455.37h-36a1.08,1.08,0,0,1,0-2.15h36a1.08,1.08,0,0,1,0,2.15Z" fill="#e6e6e6"/>
<rect x="227.58" y="425.4" width="5.37" height="5.37" fill="#787878" opacity="0.29" data-primary="true"/>
<rect x="240.46" y="425.4" width="5.37" height="5.37" fill="#ccc"/>
<rect x="290.92" y="451.61" width="5.37" height="5.37" fill="#787878" opacity="0.29" data-primary="true"/>
<rect x="303.8" y="451.61" width="5.37" height="5.37" fill="#ccc"/>
<path d="M355.32,512.93H298.43a1.08,1.08,0,0,1,0-2.15h56.89a1.08,1.08,0,1,1,0,2.15Z" fill="#e6e6e6"/>
<path d="M416,512.93H388.06a1.08,1.08,0,0,1,0-2.15H416a1.08,1.08,0,1,1,0,2.15Z" fill="#e6e6e6"/>
<rect x="361.77" y="509.17" width="5.37" height="5.37" fill="#ccc"/>
<rect x="374.65" y="509.17" width="5.37" height="5.37" fill="#787878" opacity="0.29" data-primary="true"/>
<path d="M416,455.37H375.72a1.08,1.08,0,0,1,0-2.15H416a1.08,1.08,0,1,1,0,2.15Z" fill="#e6e6e6"/>
<rect x="353.18" y="451.61" width="5.37" height="5.37" fill="#ccc"/>
<rect x="366.06" y="451.61" width="5.37" height="5.37" fill="#787878" opacity="0.29" data-primary="true"/>
<path d="M205,485H131a1.08,1.08,0,0,1,0-2.15H205a1.08,1.08,0,0,1,0,2.15Z" fill="#e6e6e6"/>
<path d="M349.42,485h-52.6a1.08,1.08,0,0,1,0-2.15h52.6a1.08,1.08,0,0,1,0,2.15Z" fill="#e6e6e6"/>
<path d="M416,485H363.38a1.08,1.08,0,1,1,0-2.15H416a1.08,1.08,0,1,1,0,2.15Z" fill="#e6e6e6"/>
<rect x="207.19" y="481.26" width="5.37" height="5.37" fill="#ccc"/>
<rect x="220.07" y="481.26" width="5.37" height="5.37" fill="#787878" opacity="0.29" data-primary="true"/>
<rect x="231.88" y="481.26" width="5.37" height="5.37" fill="#ccc"/>
<path d="M256.57,512.93H131a1.08,1.08,0,0,1,0-2.15h125.6a1.08,1.08,0,0,1,0,2.15Z" fill="#e6e6e6"/>
<rect x="258.71" y="509.17" width="5.37" height="5.37" fill="#ccc"/>
<rect x="271.59" y="509.17" width="5.37" height="5.37" fill="#787878" opacity="0.29" data-primary="true"/>
<rect x="283.4" y="509.17" width="5.37" height="5.37" fill="#ccc"/>
<rect x="244.76" y="481.26" width="5.37" height="5.37" fill="#787878" opacity="0.29" data-primary="true"/>
<rect x="259.79" y="481.26" width="5.37" height="5.37" fill="#ccc"/>
<rect x="271.59" y="481.26" width="5.37" height="5.37" fill="#787878" opacity="0.29" data-primary="true"/>
<rect x="284.48" y="481.26" width="5.37" height="5.37" fill="#ccc"/>
<path d="M417.59,429.16H358a1.08,1.08,0,1,1,0-2.15h59.58a1.08,1.08,0,0,1,0,2.15Z" fill="#e6e6e6"/>
<rect x="330.63" y="425.4" width="5.37" height="5.37" fill="#787878" opacity="0.29" data-primary="true"/>
<rect x="343.52" y="425.4" width="5.37" height="5.37" fill="#ccc"/>
<rect x="51.53" y="436.18" width="103.05" height="64.41" fill="#787878" data-primary="true"/>
<g opacity="0.3">
<path d="M88.5,485.36a1.06,1.06,0,0,1-.74-.3l-15.5-14.83a1.06,1.06,0,0,1,0-1.54l15.49-15a1.07,1.07,0,0,1,1.52,0,1.08,1.08,0,0,1,0,1.52l-14.7,14.25,14.69,14.06a1.07,1.07,0,0,1,0,1.52A1.1,1.1,0,0,1,88.5,485.36Z" fill="#fff"/>
</g>
<g opacity="0.3">
<path d="M119.16,485.36a1.07,1.07,0,0,1-.74-1.84l14.69-14.26L118.42,455.2a1.07,1.07,0,0,1,1.48-1.55l15.5,14.83a1.07,1.07,0,0,1,.33.77,1.08,1.08,0,0,1-.32.78l-15.5,15A1.08,1.08,0,0,1,119.16,485.36Z" fill="#fff"/>
</g>
<g opacity="0.3">
<path d="M96.62,483.41a1.11,1.11,0,0,1-.5-.12,1.07,1.07,0,0,1-.45-1.45l14-26.83a1.08,1.08,0,1,1,1.91,1l-14,26.83A1.06,1.06,0,0,1,96.62,483.41Z" fill="#fff"/>
</g>
<rect x="434.76" y="367.48" width="11.81" height="208.25" fill="#999"/>
<rect x="441.2" y="367.48" width="5.37" height="208.25" opacity="0.1"/>
<rect x="471.26" y="368.01" width="11.81" height="172.29" fill="#999"/>
<rect x="477.7" y="368.01" width="5.37" height="172.29" opacity="0.1"/>
<rect x="728.89" y="367.48" width="11.81" height="208.25" fill="#999"/>
<rect x="735.33" y="367.48" width="5.37" height="208.25" opacity="0.1"/>
<rect x="758.95" y="354.06" width="11.81" height="186.25" fill="#999"/>
<rect x="765.39" y="354.06" width="5.37" height="186.25" opacity="0.1"/>
<path d="M688.1,271.94h40.53a4.55,4.55,0,0,1,4.55,4.55v67.37a0,0,0,0,1,0,0H688.1a0,0,0,0,1,0,0V271.94A0,0,0,0,1,688.1,271.94Z" fill="#b3b3b3"/>
<polygon points="421.88 364.26 477.27 336.37 786.88 336.37 750.36 364.26 421.88 364.26" fill="#ccc"/>
<path d="M542.11,559.63l-32.5,25.42S496,597.2,507.76,604.71c0,0,17.17,10.74,31.13-7.51l19.37-31.64Z" fill="#787878" data-primary="true"/>
<path d="M505.61,596.12c8,8.68,20.58,6.87,28.45-1,3.7-3.79,7-8.33,10.52-12.3,3.08-3.62,7.51-8.79,10.65-12.28-2.8,3.74-7.06,9.09-10,12.81-3.41,4.12-6.73,8.65-10.42,12.54-8.21,8.11-21.45,9.88-29.19.26Z" opacity="0.2"/>
<path d="M512.32,583.74c6.45-.09,13.31,2.42,17.35,7.63a15.61,15.61,0,0,1,2.79,5.84c-.26-.47-.51-1-.74-1.43a8.51,8.51,0,0,0-.81-1.37c-4-6.39-11.44-9.4-18.59-10.67Z" opacity="0.2"/>
<path d="M519.56,580c4.83-.65,11.72.93,12.9,6.4-2.62-4.61-8.1-5.41-12.9-6.4Z" opacity="0.2"/>
<path d="M523.86,575.73c4.82-.65,11.72.93,12.89,6.39-2.61-4.6-8.1-5.4-12.89-6.39Z" opacity="0.2"/>
<path d="M532.45,569.29c4.82-.65,11.72.93,12.89,6.39-2.61-4.61-8.1-5.4-12.89-6.39Z" opacity="0.2"/>
<path d="M550.16,544.06l-8,15.57s-3.32,4,1.25,6.48a8.52,8.52,0,0,0,4.06,1h7.9a3.61,3.61,0,0,0,2.94-1.51L568,551.93S554.41,546.7,550.16,544.06Z" fill="#f9b499"/>
<polygon points="548.32 510.23 551.84 520.86 557.18 505.66 548.32 510.23" fill="#f9b499"/>
<path d="M710.77,332.4c0,8.24-5.5,8.24-5.5,8.24l-15,5.37c-6.68,2.23-9.44,1.89-10.5,1.46a1.62,1.62,0,0,0-1.36.1.24.24,0,0,1-.08.06,11.71,11.71,0,0,1-3.82,1.75h0c-2.89.58-2.48-2.31-2.48-2.31a12.77,12.77,0,0,0,.2-1.54,9.91,9.91,0,0,0-5.8-9.37,26.59,26.59,0,0,0-4.77-1.68,6.38,6.38,0,0,0-3.07,0l-8.33,1.91H608.39L570,335.27a98.24,98.24,0,0,1,12.58-65.48,86.2,86.2,0,0,1,8.82-12.47c.72-.84,1.14-1.27,1.14-1.27l2.37-3.43s32,2.14,32.37,1.07,22.15-14,22.15-14l30.76,13a10.63,10.63,0,0,1,3.59,2.59c6.62,6.85,11.81,23.17,11.81,23.17l14,46.16A30.89,30.89,0,0,1,710.77,332.4Z" fill="#787878" data-primary="true"/>
<path d="M675.8,305s-30.74,5-53.75.22c-.59-.12-1.17-.27-1.75-.43A88.92,88.92,0,0,0,592.56,302l-22.06-.18-1.09,7.3h36.87s12,.39,21.7,3.61c0,0,9.66,3.22,29,1.07l21.82-2.66Z" fill="#282728" data-secondary="true"/>
<path d="M683.8,255.21c-20.39,2.6-56.89,14.58-56.89,14.58-8.59-6.44-35.49-12.47-35.49-12.47.72-.84,1.14-1.27,1.14-1.27l2.37-3.43s32,2.14,32.37,1.07,22.15-14,22.15-14l30.76,13A10.63,10.63,0,0,1,683.8,255.21Z" opacity="0.2"/>
<path d="M620.1,254.32a12.38,12.38,0,0,1-1.24.26c-7.26,1.28-14.75-1.87-20.74-8a43,43,0,0,1-10.73-19.86c-4.59-18.58,2.63-36.33,16.12-39.66s28.13,9,32.72,27.59S633.6,251,620.1,254.32Z" fill="#f9b499"/>
<ellipse cx="639.26" cy="215.05" rx="1.61" ry="3.22" fill="none" stroke="red" stroke-miterlimit="10" stroke-width="0.75"/>
<path d="M651.6,210.75s17.18,9.45-10.73,18.14a15.44,15.44,0,0,1-.54-3.65,15.8,15.8,0,0,1,.54-4.54l-8.59-4.36s-4.67.85-7.17-4.52c0,0-8.93,0-7.86-6.44,0,0-6.44,4.3-8.59-1.07,0,0-9.69,6.88-19.33-4.62,0,0-4.28,7.84-3,21,0,0-6.34,5.08-9.93.38a6.63,6.63,0,0,1-1.28-3.77,5.58,5.58,0,0,1,3.22-5.49s-7.77-2.89-7.56-9.28a10.2,10.2,0,0,1,1.41-4.67s1.61-4,7.63-2.31h0a19.17,19.17,0,0,1,3.1,1.24s-8.21-17.26,3.4-28.49c0,0,19.14-19.82,26.66,4.87,0,0,6.55-10.14,17-7.62h0a15.76,15.76,0,0,1,2.25.72s7.51,2,6.44,14.1c0,0,9.66-8.28,18.25,1.38,0,0,6.44,7.89,0,16.28C657,198.05,660.19,205.38,651.6,210.75Z" fill="#282728" data-secondary="true"/>
<path d="M590.41,197.6s-3.22-10.46,6.44-16.91c0,0,6.93-4.51,16.49,1.46a23.89,23.89,0,0,1,2.73,2.07,16.44,16.44,0,0,0,10.59,4.11s11-.47,12.6,12c0,0-12.35-10.72-21.47-5.54,0,0-4.83-15.22-17.72-10.93C600.07,183.91,592.56,186.06,590.41,197.6Z" opacity="0.2"/>
<path d="M579.79,195.56c-5.23.93-9,7-9,7a10.2,10.2,0,0,1,1.41-4.67S573.77,193.84,579.79,195.56Z" opacity="0.2"/>
<path d="M651.6,210.75s17.18,9.45-10.73,18.14a7.4,7.4,0,0,1-.54-3.65,7.26,7.26,0,0,1,.54-2.07l4.29-6.83h0c3.22-1.93,3.22-6.66,3.22-6.66a10.45,10.45,0,0,0,4.63-3.63,8.74,8.74,0,0,0,1.09-8.24c-2.23-5.68-8.94-4.09-8.94-4.09,2.15-16-7.52-10.85-7.52-10.85-1-14.52-7.22-17.15-7.61-17.3a15.76,15.76,0,0,1,2.25.72s7.51,2,6.44,14.1c0,0,9.66-8.28,18.25,1.38,0,0,6.44,7.89,0,16.28C657,198.05,660.19,205.38,651.6,210.75Z" opacity="0.2"/>
<path d="M659.11,241.88l-26.83,22.77c-4.3,3.45-6.44.85-6.44.85l-1.19-1.87-5.79-9c20.4-4.65,18.67-31.41,18.67-31.41h3.34a17.63,17.63,0,0,0,2.14,11.2c3.91-1.57,9-1.42,11.4-1.23a14.8,14.8,0,0,1,2.89.49C665.93,236,659.11,241.88,659.11,241.88Z" fill="#f9b499"/>
<path d="M659.11,241.88l-26.83,22.77c-4.3,3.45-6.44.85-6.44.85l-1.19-1.87c11.69-5.09,23-18.83,23-18.83,4.06-6-2.64-9.53-4.26-10.28a.16.16,0,0,1,0-.29c3.86-1.42,8.68-1.27,11-1.09a14.8,14.8,0,0,1,2.89.49C665.93,236,659.11,241.88,659.11,241.88Z" fill="#f7a48b"/>
<path d="M618.86,254.58l3.07,4.81s18.66-10.53,15-26.36C637,233,635.5,251.18,618.86,254.58Z" fill="#f7a48b"/>
<path d="M599,253.69a55.57,55.57,0,0,1,18.79,6.51" fill="none" stroke="red" stroke-miterlimit="10" stroke-width="0.75"/>
<path d="M710.77,332.4c0,8.24-5.5,8.24-5.5,8.24l-15,5.37c-6.68,2.23-9.44,1.89-10.5,1.46a1.62,1.62,0,0,0-1.36.1c.36-.24,1.68-1.46-.08-5l-5.63-8.42a1.13,1.13,0,0,1,.39-1.6,1.07,1.07,0,0,1,.55-.14,1.12,1.12,0,0,1,.91.46l7.14,9.93s1.07,4.29,15-2.15C696.69,340.64,708.75,336,710.77,332.4Z" opacity="0.2"/>
<path d="M674.48,349.38h0c-2.89.58-2.48-2.31-2.48-2.31a12.77,12.77,0,0,0,.2-1.54,9.91,9.91,0,0,0-5.8-9.37,26.59,26.59,0,0,0-4.77-1.68s8.22-3.51,12.51,7.22C674.14,341.71,675.46,346.35,674.48,349.38Z" opacity="0.2"/>
<path d="M677.36,323.46s-14,5.89-18.8,11l-8.33,1.91H608.39L570,335.27a98.24,98.24,0,0,1,12.58-65.48c.3,0,8.89,2.15,17.47,32.21,0,0,8.53,31.81,22,30.4h23.5s21.08.73,21.08-13.23V297.7s.65-8.42,4.09-3.13L681.66,317S683.8,321.32,677.36,323.46Z" opacity="0.2"/>
<path d="M680.58,258c-8.42,6.71-12.77,17.28-12.88,27.91-.1-1.33-.27-2.68-.25-4,0-9.45,4.89-19.05,13.13-23.89Z" opacity="0.2"/>
<path d="M640.87,324h0a.54.54,0,0,1-.52-.55l1.07-32.21c0-21.29,5.35-36.51,5.4-36.66a.54.54,0,0,1,.69-.32.53.53,0,0,1,.32.68c0,.15-5.33,15.2-5.33,36.32l-1.08,32.22A.54.54,0,0,1,640.87,324Z" fill="#282728" data-secondary="true"/>
<path d="M614,327.22h0a.54.54,0,0,1-.52-.55l1.08-31.13a208.17,208.17,0,0,1,2.69-33.9.53.53,0,0,1,.62-.43.54.54,0,0,1,.43.63,208.45,208.45,0,0,0-2.67,33.71l-1.07,31.15A.55.55,0,0,1,614,327.22Z" fill="#282728" data-secondary="true"/>
<g opacity="0.2">
<path d="M640.87,324h0a.54.54,0,0,1-.52-.55l1.07-32.21c0-21.29,5.35-36.51,5.4-36.66a.54.54,0,0,1,.69-.32.53.53,0,0,1,.32.68c0,.15-5.33,15.2-5.33,36.32l-1.08,32.22A.54.54,0,0,1,640.87,324Z"/>
<path d="M614,327.22h0a.54.54,0,0,1-.52-.55l1.08-31.13a208.17,208.17,0,0,1,2.69-33.9.53.53,0,0,1,.62-.43.54.54,0,0,1,.43.63,208.45,208.45,0,0,0-2.67,33.71l-1.07,31.15A.55.55,0,0,1,614,327.22Z"/>
</g>
<path d="M706.34,371.77c0,.17,0,8.76-2.14,25.76l-.34,2.43a58.67,58.67,0,0,0-.52,7.27c-.06,3.84-2.56,11.15-21.3,8.21.49-.83.94-1.65,1.36-2.49l.35-.68c1.57-3,3.69-7.58,4.35-11.52,0,0-59-5.36-78.37-12.88,0,0-28.3-11.81-38.84-8.05l-8.39,7s-7.51-2.15,3.22-15Z" fill="#787878" data-primary="true"/>
<path d="M688.1,400.75s13.8.92,13.29,7a4,4,0,0,1-1.61,2.85c-1.84,1.41-6.25,3.29-16.15,1.89A63,63,0,0,0,688.1,400.75Z" opacity="0.2"/>
<path d="M564.14,385.44s-6.33-4,6.75-5.62Z" opacity="0.2"/>
<path d="M688.1,400.75a53.84,53.84,0,0,1-4.35,11.52l-.35.68c-.23.43-.44.81-.63,1.15s-.47.89-.73,1.34c-13.3,23.42-41.56,44.44-53.06,52.37a12.19,12.19,0,0,0-5.27,9.22c-2.38,36.84-19.34,68.64-19.34,68.64-3.61,5.17-9,7.66-15,8.46-19.1,2.58-45.12-11.68-45.12-11.68l14-39.72c11.81-44,23.61-56.89,23.61-56.89l26.54-55.12,1.37-2.85C629.06,395.39,688.1,400.75,688.1,400.75Z" fill="#282728" data-secondary="true"/>
<path d="M688.1,400.75a53.84,53.84,0,0,1-4.35,11.52l-.35.68c-.23.43-.44.81-.63,1.15s-.47.89-.73,1.34c-13.3,23.42-41.56,44.44-53.06,52.37a12.19,12.19,0,0,0-5.27,9.22c-2.38,36.84-19.34,68.64-19.34,68.64-3.61,5.17-9,7.66-15,8.46,20-25.72,31.27-83,31.27-83-.89-13.33,38.47-47.86,38.47-47.86,15-15-4.29-19.33-4.29-19.33-17.27-2.72-39.92-10.84-46.46-13.25l1.37-2.85C629.06,395.39,688.1,400.75,688.1,400.75Z" opacity="0.2"/>
<path d="M589.37,430.17l-33.31,13.52,13,26s-5.54,16.19-11.4,35.76c0,0-13.42,9.12-27.37,8.05,0,0-11.81-30.06-18.25-61.19,0,0-8.59-18.25,6.44-30.06L562,387.05l8.93-7.23s6.64-4.83,38.84,8.05Z" fill="#282728" data-secondary="true"/>
<path d="M547.62,532.88,526.35,549.3a27.56,27.56,0,0,1-6.81,3.93c-3.21,1.25-7.85,4-6.84,9.17a8.45,8.45,0,0,0,5.07,6.09c2.55,1.06,6.59,1.78,12.53.37l11.81-9.23,7.47-14.54-5.33-2.64Z" fill="#787878" data-primary="true"/>
<path d="M547.62,532.88,526.35,549.3a27.56,27.56,0,0,1-6.81,3.93c-3.21,1.25-7.85,4-6.84,9.17a8.45,8.45,0,0,0,5.07,6.09c2.55,1.06,6.59,1.78,12.53.37l11.81-9.23,7.47-14.54-5.33-2.64Z" opacity="0.2"/>
<path d="M589.37,430.17l-33.31,13.52,13,26a370.36,370.36,0,0,1-11.89,36s-12.93,8.88-26.88,7.81c39.72-3.22,20.78-67.22,20.78-67.22-4.38-9.78,2.19-12.65,6.18-13.48a53.87,53.87,0,0,0,7.5-2.12l10.06-3.7a29.52,29.52,0,0,0,16.91-15.53,27.2,27.2,0,0,0,2.23-8.31,14.25,14.25,0,0,0-10.3-15c-8.42-2.48-16.86-1.84-21.7-1.1l8.93-7.23s6.64-4.83,38.84,8.05Z" opacity="0.2"/>
<path d="M512.56,561c8,4.49,17.84,3.92,26,.25,1.19-.51,2.33-1.14,3.54-1.66-1.08.73-2.18,1.45-3.3,2.13-8,4.53-18.78,5.1-26.25-.72Z" opacity="0.2"/>
<path d="M524.65,550.52c4.14,1.84,12.18,6.84,12.1,11.9-.72-2.81-3.3-4.59-5.35-6.46s-4.5-3.57-6.75-5.44Z" opacity="0.2"/>
<path d="M530.3,546.25c3.1.44,5.52,3.24,6.45,6.1-2.23-2.05-4-4.27-6.45-6.1Z" opacity="0.2"/>
<path d="M534.32,543.14a9.55,9.55,0,0,1,6.62,6.16c-2.17-2.19-4.35-4-6.62-6.16Z" opacity="0.2"/>
<path d="M538.89,539.61a11.81,11.81,0,0,1,5.36,6.61,29.31,29.31,0,0,1-5.36-6.61Z" opacity="0.2"/>
<rect x="421.88" y="364.26" width="328.48" height="7.51" fill="#b3b3b3"/>
<polygon points="750.36 364.26 750.36 371.77 786.86 342.79 786.88 336.37 750.36 364.26" fill="#999"/>
<path d="M507.76,344.93h98.07l-7.33-63.74a5.61,5.61,0,0,0-5.57-5h-90a3,3,0,0,0-2.93,3.31Z" fill="#787878" data-primary="true"/>
<path d="M605.83,344.93H507.76L500,279.54a3,3,0,0,1,2.95-3.31h90a5.61,5.61,0,0,1,5.56,5Z" fill="#fff" opacity="0.3"/>
<polygon points="583.53 276.23 507.76 341.71 506.12 329.04 567.52 276.23 583.53 276.23" fill="#fff" opacity="0.3"/>
<path d="M517.07,344.93l79.55-67.31a6,6,0,0,1,1.88,3.57l.38,3.34-71.09,60.4Z" fill="#fff" opacity="0.3"/>
<rect x="507.76" y="344.93" width="94.46" height="6.44" fill="#787878" data-primary="true"/>
<rect x="602.22" y="344.93" width="29.49" height="6.44" fill="#787878" data-primary="true"/>
<rect x="602.22" y="344.93" width="29.49" height="6.44" opacity="0.2"/>
<polygon points="419.73 353.52 466.38 353.52 499.97 333.94 459.85 333.94 419.73 353.52" fill="#fff"/>
<rect x="419.73" y="353.52" width="46.65" height="4.65" fill="#e6e6e6"/>
<polygon points="499.97 333.94 499.97 339.8 466.38 358.17 466.38 353.52 499.97 333.94" fill="#ccc"/>
<polygon points="499.97 333.94 499.97 339.8 466.38 358.17 466.38 353.52 499.97 333.94" opacity="0.1"/>
<path d="M658.56,334.46s-13.47,1.87-20.95,12.08c0,0-10.05,9.15-.18,7.53,0,0,.47,4.68,8.39,1.53,0,0,1.37,3.31,10-1.53,0,0,8.64-4.84,16.16-7C672,347.08,675.17,334.71,658.56,334.46Z" fill="#f9b499"/>
<path d="M646,343.86a40.12,40.12,0,0,1-8.55,10.21A40.49,40.49,0,0,1,646,343.86Z" fill="#f7a48b"/>
<path d="M645.82,355.6a24.61,24.61,0,0,1,6.85-7.82,24.71,24.71,0,0,1-6.85,7.82Z" fill="#f7a48b"/>
<ellipse cx="638.72" cy="215.58" rx="6.44" ry="8.05" fill="#f9b499"/>
<path d="M640.87,228.89s12.2-4.93,24.24-3.72a26.56,26.56,0,0,1,17.33,9.17c4.85,5.6,11.54,15.1,4.38,18.3a8.59,8.59,0,0,1-7.29-.33c-5-2.49-17.91-6.91-47.79,12.65l27.37-23.08s6.49-6.48-3.5-8.53a13.52,13.52,0,0,0-2.62-.25,46.27,46.27,0,0,0-10,1.27S640.87,230.93,640.87,228.89Z" fill="#787878" data-primary="true"/>
<path d="M640.87,228.89s12.2-4.93,24.24-3.72a26.56,26.56,0,0,1,17.33,9.17c4.85,5.6,11.54,15.1,4.38,18.3a8.59,8.59,0,0,1-7.29-.33c-5-2.49-17.91-6.91-47.79,12.65l27.37-23.08s6.49-6.48-3.5-8.53a13.52,13.52,0,0,0-2.62-.25,46.27,46.27,0,0,0-10,1.27S640.87,230.93,640.87,228.89Z" fill="#fff" opacity="0.3"/>
<path d="M674.14,234.37c-5.73,6.95-13.48,12.06-21.25,16.49-1.15.58-2.28,1.2-3.44,1.76,8.36-5.92,17-11.41,24.69-18.25Z" fill="#fff" opacity="0.3"/>
<path d="M683.8,238.66C679,244,671.85,246.84,664.89,248c6.47-2.57,13.26-5.24,18.91-9.35Z" fill="#fff" opacity="0.3"/>
<path d="M625.84,265.5c-4.44-2.67-21.36-6.8-27.08-8.15a23.81,23.81,0,0,0-3.37-.5c-4.81-.45-3.9-3.16-3.9-3.16,0-4.29,6.63-7.09,6.63-7.09,6,6.11,13.48,9.26,20.74,8Z" fill="#787878" data-primary="true"/>
<path d="M625.84,265.5c-4.44-2.67-21.36-6.8-27.08-8.15a23.81,23.81,0,0,0-3.37-.5c-4.81-.45-3.9-3.16-3.9-3.16,0-4.29,6.63-7.09,6.63-7.09,6,6.11,13.48,9.26,20.74,8Z" fill="#fff" opacity="0.3"/>
<circle cx="551.23" cy="311.12" r="8.05" fill="#fff"/>
</svg>

Before

Width:  |  Height:  |  Size: 23 KiB

View file

@ -1,9 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
<style>
path { fill: #000; }
@media (prefers-color-scheme: dark) {
path { fill: #FFF; }
}
</style>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M346-250h268v-52H346v52Zm0-144h268v-52H346v52Zm-69.97 278q-27.03 0-45.53-18.65T212-180.31v-599.38q0-27.01 18.65-45.66Q249.3-844 276.31-844H586l162 162v501.69q0 27.01-18.66 45.66Q710.68-116 683.65-116H276.03ZM548-644v-148H276.31q-4.62 0-8.46 3.85-3.85 3.84-3.85 8.46v599.38q0 4.62 3.85 8.46 3.84 3.85 8.46 3.85h407.38q4.62 0 8.46-3.85 3.85-3.84 3.85-8.46V-644H548ZM264-792v169-169V-168v-624Z"/></svg>

Before

Width:  |  Height:  |  Size: 749 B

After

Width:  |  Height:  |  Size: 515 B

View file

@ -28,7 +28,7 @@ if (breadcrumbList[0] === "tags" && !isNaN(Number(breadcrumbList[2]))) {
class="font-light [&>li]:inline [&>li:not(:last-child)>a]:hover:opacity-100"
>
<li>
<a href="/" class="opacity-80">Home</a>
<a href="/" class="opacity-80">Accueil</a>
<span aria-hidden="true" class="opacity-80">&raquo;</span>
</li>
{

View file

@ -43,7 +43,7 @@ const time = datetime.format("hh:mm A"); // e.g., '08:30 PM'
{
modDatetime && modDatetime > pubDatetime ? (
<span class:list={["text-sm italic", { "sm:text-base": size === "lg" }]}>
Updated:
Mis à jour:
</span>
) : (
<span class="sr-only">Published:</span>

View file

@ -18,9 +18,9 @@ const { noMarginTop = false } = Astro.props;
>
<Socials centered />
<div class="my-2 flex flex-col items-center whitespace-nowrap sm:flex-row">
<span>Copyright &#169; {currentYear}</span>
<span>Copyleft &#127279;</span>
<span class="hidden sm:inline">&nbsp;|&nbsp;</span>
<span>All rights reserved.</span>
<span>De toute façon je sais pas ce que vous en ferez</span>
</div>
</div>
</footer>

View file

@ -79,8 +79,8 @@ const isActive = (path: string) => {
</a>
</li>
<li class="col-span-2">
<a href="/about" class:list={{ "active-nav": isActive("/about") }}>
About
<a href="/apropos" class:list={{ "active-nav": isActive("/apropos") }}>
À propos
</a>
</li>
{
@ -105,16 +105,16 @@ const isActive = (path: string) => {
}
<li class="col-span-1 flex items-center justify-center">
<LinkButton
href="/search"
href="/recherche"
class:list={[
"focus-outline flex p-3 sm:p-1",
{ "[&>svg]:stroke-accent": isActive("/search") },
{ "[&>svg]:stroke-accent": isActive("/recherche") },
]}
ariaLabel="search"
title="Search"
ariaLabel="recherche"
title="Recherche"
>
<IconSearch />
<span class="sr-only">Search</span>
<span class="sr-only">Recherche</span>
</LinkButton>
</li>
{

View file

@ -8,7 +8,7 @@ const URL = Astro.url;
<div
class="flex flex-col flex-wrap items-center justify-center gap-1 sm:items-start"
>
<span class="italic">Share this post on:</span>
<!-- <span class="italic">Share this post on:</span> -->
<div class="text-center">
{
SHARE_LINKS.map(social => (

View file

@ -1,9 +1,9 @@
export const SITE = {
website: "https://astro-paper.pages.dev/", // replace this with your deployed domain
author: "Sat Naing",
profile: "https://satnaing.dev/",
website: "https://blog.oblic-parallels.fr/", // replace this with your deployed domain
author: "Gu://em_",
profile: "https://oblic-parallels.fr",
desc: "A minimal, responsive and SEO-friendly Astro blog theme.",
title: "AstroPaper",
title: "Oblog Parallels",
ogImage: "astropaper-og.jpg",
lightAndDarkMode: true,
postPerIndex: 4,
@ -12,11 +12,11 @@ export const SITE = {
showArchives: true,
showBackButton: true, // show back button in post detail
editPost: {
enabled: true,
text: "Suggest Changes",
url: "https://github.com/satnaing/astro-paper/edit/main/",
enabled: false,
text: "Proposer un changement",
url: "https://openai.com",
},
dynamicOgImage: true,
lang: "en", // html lang code. Set this empty and default will be "en"
timezone: "Asia/Bangkok", // Default global timezone (IANA format) https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
lang: "fr", // html lang code. Set this empty and default will be "en"
timezone: "Europe/Paris", // Default global timezone (IANA format) https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
} as const;

View file

@ -1,75 +1,75 @@
import IconMail from "@/assets/icons/IconMail.svg";
import IconGitHub from "@/assets/icons/IconGitHub.svg";
import IconBrandX from "@/assets/icons/IconBrandX.svg";
import IconLinkedin from "@/assets/icons/IconLinkedin.svg";
import IconWhatsapp from "@/assets/icons/IconWhatsapp.svg";
import IconFacebook from "@/assets/icons/IconFacebook.svg";
import IconTelegram from "@/assets/icons/IconTelegram.svg";
import IconPinterest from "@/assets/icons/IconPinterest.svg";
import { SITE } from "@/config";
// import IconMail from "@/assets/icons/IconMail.svg";
// import IconGitHub from "@/assets/icons/IconGitHub.svg";
// import IconBrandX from "@/assets/icons/IconBrandX.svg";
// import IconLinkedin from "@/assets/icons/IconLinkedin.svg";
// import IconWhatsapp from "@/assets/icons/IconWhatsapp.svg";
// import IconFacebook from "@/assets/icons/IconFacebook.svg";
// import IconTelegram from "@/assets/icons/IconTelegram.svg";
// import IconPinterest from "@/assets/icons/IconPinterest.svg";
// import { SITE } from "@/config";
export const SOCIALS = [
{
name: "Github",
href: "https://github.com/satnaing/astro-paper",
linkTitle: ` ${SITE.title} on Github`,
icon: IconGitHub,
},
{
name: "X",
href: "https://x.com/username",
linkTitle: `${SITE.title} on X`,
icon: IconBrandX,
},
{
name: "LinkedIn",
href: "https://www.linkedin.com/in/username/",
linkTitle: `${SITE.title} on LinkedIn`,
icon: IconLinkedin,
},
{
name: "Mail",
href: "mailto:yourmail@gmail.com",
linkTitle: `Send an email to ${SITE.title}`,
icon: IconMail,
},
// {
// name: "Github",
// href: "https://github.com/satnaing/astro-paper",
// linkTitle: ` ${SITE.title} on Github`,
// icon: IconGitHub,
// },
// {
// name: "X",
// href: "https://x.com/username",
// linkTitle: `${SITE.title} on X`,
// icon: IconBrandX,
// },
// {
// name: "LinkedIn",
// href: "https://www.linkedin.com/in/username/",
// linkTitle: `${SITE.title} on LinkedIn`,
// icon: IconLinkedin,
// },
// {
// name: "Mail",
// href: "mailto:yourmail@gmail.com",
// linkTitle: `Send an email to ${SITE.title}`,
// icon: IconMail,
// },
] as const;
export const SHARE_LINKS = [
{
name: "WhatsApp",
href: "https://wa.me/?text=",
linkTitle: `Share this post via WhatsApp`,
icon: IconWhatsapp,
},
{
name: "Facebook",
href: "https://www.facebook.com/sharer.php?u=",
linkTitle: `Share this post on Facebook`,
icon: IconFacebook,
},
{
name: "X",
href: "https://x.com/intent/post?url=",
linkTitle: `Share this post on X`,
icon: IconBrandX,
},
{
name: "Telegram",
href: "https://t.me/share/url?url=",
linkTitle: `Share this post via Telegram`,
icon: IconTelegram,
},
{
name: "Pinterest",
href: "https://pinterest.com/pin/create/button/?url=",
linkTitle: `Share this post on Pinterest`,
icon: IconPinterest,
},
{
name: "Mail",
href: "mailto:?subject=See%20this%20post&body=",
linkTitle: `Share this post via email`,
icon: IconMail,
},
// {
// name: "WhatsApp",
// href: "https://wa.me/?text=",
// linkTitle: `Share this post via WhatsApp`,
// icon: IconWhatsapp,
// },
// {
// name: "Facebook",
// href: "https://www.facebook.com/sharer.php?u=",
// linkTitle: `Share this post on Facebook`,
// icon: IconFacebook,
// },
// {
// name: "X",
// href: "https://x.com/intent/post?url=",
// linkTitle: `Share this post on X`,
// icon: IconBrandX,
// },
// {
// name: "Telegram",
// href: "https://t.me/share/url?url=",
// linkTitle: `Share this post via Telegram`,
// icon: IconTelegram,
// },
// {
// name: "Pinterest",
// href: "https://pinterest.com/pin/create/button/?url=",
// linkTitle: `Share this post on Pinterest`,
// icon: IconPinterest,
// },
// {
// name: "Mail",
// href: "mailto:?subject=See%20this%20post&body=",
// linkTitle: `Share this post via email`,
// icon: IconMail,
// },
] as const;

View file

@ -1,91 +0,0 @@
---
author: Sat Naing
pubDatetime: 2023-01-30T15:57:52.737Z
title: AstroPaper 2.0
slug: astro-paper-2
featured: false
ogImage: https://user-images.githubusercontent.com/53733092/215771435-25408246-2309-4f8b-a781-1f3d93bdf0ec.png
tags:
- release
description: AstroPaper with the enhancements of Astro v2. Type-safe markdown contents, bug fixes and better dev experience etc.
---
Astro 2.0 has been released with some cool features, breaking changes, DX improvements, better error overlay and so on. AstroPaper takes advantage of those cool features, especially Content Collections API.
<!-- ![Introducing AstroPaper 2.0](https://user-images.githubusercontent.com/53733092/215683840-dc2502f5-8c5a-44f0-a26c-4e7180455056.png) -->
![Introducing AstroPaper 2.0](https://user-images.githubusercontent.com/53733092/215771435-25408246-2309-4f8b-a781-1f3d93bdf0ec.png)
## Table of contents
## Features & Changes
### Type-safe Frontmatters and Redefined Blog Schema
Frontmatter of AstroPaper 2.0 markdown contents are now type-safe thanks to Astros Content Collections. Blog schema is defined inside the `src/content/_schemas.ts` file.
### New Home for Blog contents
All the blog posts were moved from `src/contents` to `src/content/blog` directory.
### New Fetch API
Contents are now fetched with `getCollection` function. No relative path to the content needs to be specified anymore.
```ts
// old content fetching method
- const postImportResult = import.meta.glob<MarkdownInstance<Frontmatter>>(
"../contents/**/**/*.md",);
// new content fetching method
+ const postImportResult = await getCollection("blog");
```
### Modified Search Logic for better Search Result
In the older version of AstroPaper, when someone search some article, the search criteria keys that will be searched are `title`, `description` and `headings` (heading means all the headings h1 ~ h6 of the blog post). In AstroPaper v2, only `title` and `description` will be searched as the user types.
### Renamed Frontmatter Properties
The following frontmatter properties are renamed.
| Old Names | New Names |
| --------- | ----------- |
| datetime | pubDatetime |
| slug | postSlug |
### Default Tag for blog post
If a blog post doesn't have any tag (in other words, frontmatter property `tags` is not specified), the default tag `others` will be used for that blog post. But you can set the default tag in the `/src/content/_schemas.ts` file.
```ts
// src/contents/_schemas.ts
export const blogSchema = z.object({
// ---
// replace "others" with whatever you want
tags: z.array(z.string()).default(["others"]),
ogImage: z.string().optional(),
description: z.string(),
});
```
### New Predefined Dark Color Scheme
AstroPaper v2 has a new dark color scheme (high contrast & low contrast) which is based on Astro's dark logo. Check out [this link](https://astro-paper.pages.dev/posts/predefined-color-schemes#astro-dark) for more info.
![New Predefined Dark Color Scheme](https://user-images.githubusercontent.com/53733092/215680520-59427bb0-f4cb-48c0-bccc-f182a428d72d.svg)
### Automatic Class Sorting
AstroPaper 2.0 includes automatic class sorting with [TailwindCSS Prettier plugin](https://tailwindcss.com/blog/automatic-class-sorting-with-prettier)
### Updated Docs & README
All the [#docs](https://astro-paper.pages.dev/tags/docs/) blog posts and [README](https://github.com/satnaing/astro-paper#readme) are updated for this AstroPaper v2.
## Bug Fixes
- fix broken tags in the Blog Post page
- in a tag page, the last part of the breadcrumb is now updated to lower-case for consistency
- exclude draft posts in a tag page
- fix 'onChange value not updating issue' after a page reload

View file

@ -1,173 +0,0 @@
---
author: Sat Naing
pubDatetime: 2023-09-25T10:25:54.547Z
title: AstroPaper 3.0
slug: astro-paper-v3
featured: false
ogImage: https://github.com/satnaing/astro-paper/assets/53733092/1ef0cf03-8137-4d67-ac81-84a032119e3a
tags:
- release
description: "AstroPaper Version 3: Elevating Your Web Experience with Astro v3 and Seamless View Transitions"
---
We're excited to announce the release of AstroPaper v3, packed with new features, enhancements, and bug fixes to elevate your web development experience. Let's dive into the highlights of this release:
![AstroPaper v3](@/assets/images/AstroPaper-v3.png)
## Table of contents
## Features & Changes
### Astro v3 Integration
<video autoplay loop="loop" muted="muted" plays-inline="true">
<source src="https://github.com/satnaing/astro-paper/assets/53733092/18fdb604-1ca3-41a0-8372-1367759091ff" type="video/mp4">
<!-- <source src="/assets/docs/astro-paper-v3-view-transitions-demo.mp4" type="video/mp4"> -->
</video>
AstroPaper now fully supports [Astro v3](https://astro.build/blog/astro-3/), offering improved performance and rendering speed.
Besides, we've added support for Astro's [ViewTransitions API](https://docs.astro.build/en/guides/view-transitions/), allowing you to create captivating and dynamic transitions between views.
In the "Recent Section", only non-featured posts will be displayed to avoid duplications and better support for ViewTransitions API.
### Update OG Image Generation Logic
![Example OG Image](https://user-images.githubusercontent.com/40914272/269252964-a0dc6735-80f7-41ed-8e74-4d4d70f96891.png)
We've updated the logic for automatic OG image generation, making it even more reliable and efficient. Besides, it now supports special characters in post titles, ensuring accurate, flexible and eye-catching social media previews.
`SITE.ogImage` is now optional. If it is not specified, AstroPaper will automatically generate an OG image using `SITE.title`, `SITE.desc` and `SITE.website`
### Theme meta tag
The theme-color meta tag has been added to dynamically adapt to theme switches, ensuring a seamless user experience.
> Notice the difference at the top
**_AstroPaper v2 theme switch_**
<video autoplay loop="loop" muted="muted" plays-inline="true">
<source src="https://github.com/satnaing/astro-paper/assets/53733092/3ab5a1e8-1891-4264-a5bb-0ded69143c1a" type="video/mp4">
</video>
**_AstroPaper v3 theme switch_**
<video autoplay loop="loop" muted="muted" plays-inline="true">
<source src="https://github.com/satnaing/astro-paper/assets/53733092/8ac9deb8-d1f8-4029-86bd-6aa0def380b4" type="video/mp4">
</video>
## Other Changes
### Astro Prettier Plugin
Astro Prettier Plugin is installed out-of-the-box in order to keep the project tidy and organized.
### Minor Style Changes
The single-line code block wrapping issue has been solved, making your code snippets look pristine.
Update nav style CSS to allow adding more nav links to the navigation.
## Upgrade to AstroPaper v3
> This section is only for those who want to upgrade AstroPaper v3 from the older versions.
This section will help you migrate from AstroPaper v2 to AstroPaper v3.
Before reading the rest of the section, you might also want to check [this article](https://astro-paper.pages.dev/posts/how-to-update-dependencies/) for upgrading dependencies and AstroPaper.
## Option 1: Fresh Restart (recommended)
In this release, a lot of changes have been made\_ replacing old Astro APIs with newer APIs, bug fixes, new features etc. Thus, if you are someone who didn't make customization very much, you should follow this approach.
**_Step 1: Keep all your updated files_**
It's important to keep all the files which have been already updated. These files include
- `/src/config.ts` (didn't touch in v3)
- `/src/styles/base.css` (minor changes in v3; mentioned below)
- `/src/assets/` (didn't touch in v3)
- `/public/assets/` (didn't touch in v3)
- `/content/blog/` (it's your blog content directory 🤷🏻‍♂️)
- Any other customizations you've made.
```css
/* file: /src/styles/base.css */
@layer base {
/* Other Codes */
::-webkit-scrollbar-thumb:hover {
@apply bg-skin-card-muted;
}
/* Old code
code {
white-space: pre;
overflow: scroll;
}
*/
/* New code */
code,
blockquote {
word-wrap: break-word;
}
pre > code {
white-space: pre;
}
}
@layer components {
/* other codes */
}
```
**_Step 1: Replace everything else with AstroPaper v3_**
In this step, replace everything\_ except above files/directories (plus your customized files/directories)\_ with AstroPaper v3.
**_Step 3: Schema Updates_**
Keep in mind that `/src/content/_schemas.ts` has been replaced with `/src/content/config.ts`.
Besides, there is no longer `BlogFrontmatter` type exported from `/src/content/config.ts`.
Therefore, all the `BlogFrontmatter` type inside files need to be updated with `CollectionEntry<"blog">["data"]`.
For example: `src/components/Card.tsx`
```ts
// AstroPaper v2
import type { BlogFrontmatter } from "@content/_schemas";
export interface Props {
href?: string;
frontmatter: BlogFrontmatter;
secHeading?: boolean;
}
```
```ts
// AstroPaper v3
import type { CollectionEntry } from "astro:content";
export interface Props {
href?: string;
frontmatter: CollectionEntry<"blog">["data"];
secHeading?: boolean;
}
```
## Option 2: Upgrade using Git
This approach is not recommended for most users. You should do the "Option 1" if you can. Only do this if you know how to resolve merge conflicts and you know what you're doing.
Actually, I've already written a blog post for this case and you can check out [here](https://astro-paper.pages.dev/posts/how-to-update-dependencies/#updating-astropaper-using-git).
## Outro
Ready to explore the exciting new features and improvements in AstroPaper v3? Start [using AstroPaper](https://github.com/satnaing/astro-paper) now.
For other bug fixes and integration updates, check out the [release notes](https://github.com/satnaing/astro-paper/releases/tag/v3.0.0) to learn more.
If you encounter any bugs or face difficulties during the upgrade process, please feel free to open an issue or start a discussion on [GitHub](https://github.com/satnaing/astro-paper).

View file

@ -1,124 +0,0 @@
---
author: Sat Naing
pubDatetime: 2024-01-04T09:30:41.816Z
title: AstroPaper 4.0
slug: "astro-paper-v4"
featured: false
ogImage: ../../../assets/images/AstroPaper-v4.png
tags:
- release
description: "AstroPaper v4: ensuring a smoother and more feature-rich blogging experience."
---
Hello everyone! Wishing you a happy New Year 🎉 and all the best for 2024! We're excited to announce the release of AstroPaper v4, a significant update that introduces a range of new features, improvements, and bug fixes to elevate your blogging experience. A big thank you to all the contributors for their valuable input and efforts in making version 4 possible!
![AstroPaper v4](@/assets/images/AstroPaper-v4.png)
## Table of contents
## Major Changes
### Upgrade to Astro v4 [#202](https://github.com/satnaing/astro-paper/pull/202)
AstroPaper now leverages the power and capabilities of Astro v4. However, its a subtle upgrade and wont break most Astro users.
![Astro v4](https://astro.build/_astro/header-astro-4.YunweN9V_OmV0l.webp)
### Replace `postSlug` with Astro Content `slug` [#197](https://github.com/satnaing/astro-paper/pull/197)
The `postSlug` in the blog content schema is no longer available in AstroPaper v4. Initially Astro doesn't have a `slug` mechanism and thus we have to figure it out on our own. Since Astro v3, it supports content collection and slug features. Now, we believe it's time to adopt Astro's out-of-the-box `slug` feature.
**_file: src/content/blog/astro-paper-4.md_**
```bash
---
author: Sat Naing
pubDatetime: 2024-01-01T04:35:33.428Z
title: AstroPaper 4.0
slug: "astro-paper-v4" # if slug is not specified, it will be 'astro-paper-4' (file name).
# slug: "" ❌ cannot be an empty string
---
```
The behavior of the `slug` is slightly different now. In the previous versions of AstroPaper, if the `postSlug` is not specified in a blog post (markdown file), the title of that blog post would be slugified and used as the `slug`. However, in AstroPaper v4, if the `slug` field is not specified, the markdown file name will be used as the `slug`. One thing to keep in mind is that the `slug` field can be omitted, but it cannot be an empty string (slug: "" ❌).
If you're upgrading AstroPaper from v3 to v4, make sure to replace `postSlug` in your `src/content/blog/*.md` files with `slug`.
## New Features
### Add code-snippets for content creation [#206](https://github.com/satnaing/astro-paper/pull/206)
AstroPaper now includes VSCode snippets for new blog posts, eliminating the need for manual copy/pasting of the frontmatter and content structure (table of contents, heading, excerpt, etc.).
Read more about VSCode Snippets [here](https://code.visualstudio.com/docs/editor/userdefinedsnippets#:~:text=In%20Visual%20Studio%20Code%2C%20snippets,Snippet%20in%20the%20Command%20Palette).
<video autoplay muted="muted" controls plays-inline="true" class="border border-skin-line">
<source src="https://github.com/satnaing/astro-paper/assets/53733092/136f1903-bade-40a2-b6bb-285a3c726350" type="video/mp4">
</video>
### Add Modified Datetime in Blog Posts [#195](https://github.com/satnaing/astro-paper/pull/195)
Keep readers informed about the latest updates by displaying the modified datetime in blog posts. This not only instills user trust in the freshness of the articles but also contributes to improved SEO for the blog.
![Last Modified Date feature in AstroPaper](https://github.com/satnaing/astro-paper/assets/53733092/cc89585e-148e-444d-9da1-0d496e867175)
You can add a `modDatetime` to your blog post if you've made modifications. Now, the sorting behavior of the posts is slightly different. All posts are sorted by both `pubDatetime` and `modDatetime`. If a post has both a `pubDatetime` and `modDatetime`, its sorting position will be determined by the `modDatetime`. If not, only `pubDatetime` will be considered to determine the post's sorting order.
### Implement Back-to-Top Button [#188](https://github.com/satnaing/astro-paper/pull/188)
Enhance user navigation on your blog detail post with the newly implemented back-to-top button.
![Back to top button in AstroPaper](https://github.com/satnaing/astro-paper/assets/53733092/79854957-7877-4f19-936e-ad994b772074)
### Add Pagination in Tag Posts [#201](https://github.com/satnaing/astro-paper/pull/201)
Improve content organization and navigation with the addition of pagination in tag posts, making it easier for users to explore related content. This ensures that if a tag has many posts, readers won't be overwhelmed by all the tag-related posts.
<video autoplay loop="loop" muted="muted" plays-inline="true" class="border border-skin-line">
<source src="https://github.com/satnaing/astro-paper/assets/53733092/9bad87f5-dcf5-4b79-b67a-d6c7244cd616" type="video/mp4">
</video>
### Dynamically Generate robots.txt [#130](https://github.com/satnaing/astro-paper/pull/130)
AstroPaper v4 now dynamically generates the robots.txt file, giving you more control over search engine indexing and web crawling. Besides, sitemap URL will also be added inside `robot.txt` file.
### Add Docker-Compose File [#174](https://github.com/satnaing/astro-paper/pull/174)
Managing your AstroPaper environment is now easier than ever with the addition of a Docker-Compose file, simplifying deployment and configuration.
## Refactoring & Bug Fixes
### Replace Slugified Title with Unslugified Tag Name [#198](https://github.com/satnaing/astro-paper/pull/198)
To improve clarity, user experience and SEO, titles (`Tag: some-tag`) in tag page are no longer slugified (`Tag: Some Tag`).
![Unslugified Tag Names](https://github.com/satnaing/astro-paper/assets/53733092/2fe90d6e-ec52-467b-9c44-95009b3ae0b7)
### Implement 100svh for Min-Height ([79d569d](https://github.com/satnaing/astro-paper/commit/79d569d053036f2113519f41b0d257523d035b76))
We've updated the min-height on the body to use 100svh, offering a better UX for mobile users.
### Update Site URL as Single Source of Truth [#143](https://github.com/satnaing/astro-paper/pull/143)
The site URL is now a single source of truth, streamlining configuration and avoiding inconsistencies. Read more at this [PR](https://github.com/satnaing/astro-paper/pull/143) and its related issue(s).
### Solve Invisible Text Code Block Issue in Light Mode [#163](https://github.com/satnaing/astro-paper/pull/163)
We've fixed the invisible text code block issue in light mode.
### Decode Unicode Tag Characters in Breadcrumb [#175](https://github.com/satnaing/astro-paper/pull/175)
The last part of Tag in the breadcrumb is now decoded, making non-English Unicode characters display better.
### Update LOCALE Config to Cover Overall Locales ([cd02b04](https://github.com/satnaing/astro-paper/commit/cd02b047d2b5e3b4a2940c0ff30568cdebcec0b8))
The LOCALE configuration has been updated to cover a broader range of locales, catering to a more diverse audience.
## Outtro
We believe these updates will significantly elevate your AstroPaper experience. Thank you to everyone who contributed, solved issues, and gave stars to AstroPaper. We look forward to seeing the amazing content you create with AstroPaper v4!
Happy Blogging!
[Sat Naing](https://satnaing.dev) <br/>
Creator of AstroPaper

View file

@ -1,101 +0,0 @@
---
pubDatetime: 2025-03-08T08:18:19.693Z
title: AstroPaper 5.0
slug: astro-paper-v5
featured: true
ogImage: ../../../assets/images/AstroPaper-v5.png
tags:
- release
description: "AstroPaper v5: keep the clean look, updates under the hood."
---
At last, the long-awaited AstroPaper v5 is finally here. AstroPaper v5 keeps the same minimal & clean look, but comes with significant updates under the hood.
![AstroPaper v5](@/assets/images/AstroPaper-v5.png)
## Table of contents
## Major Changes
### Upgrade to Astro v5 [#455](https://github.com/satnaing/astro-paper/pull/455)
AstroPaper now comes with Astro v5, bringing all the new features and improvements that come with it.
### Tailwind v4
AstroPaper has been upgraded to Tailwind v4, which includes many style changes under the hood. The `tailwind.config.js` file has been removed, and now all the configuration is located within the `src/styles/global.css` file. Typography-related styles have been extracted and moved to `src/styles/typography.css`.
Due to the new behavior in TailwindCSS v4, styles inside `<style>` blocks within components have been removed and replaced with inline Tailwind classes.
Additionally, the color palette across the UI has been updated. The new palette now consists of only five colors:
```css
:root,
html[data-theme="light"] {
--background: #fdfdfd;
--foreground: #282728;
--accent: #006cac;
--muted: #e6e6e6;
--border: #ece9e9;
}
html[data-theme="dark"] {
--background: #212737;
--foreground: #eaedf3;
--accent: #ff6b01;
--muted: #343f60bf;
--border: #ab4b08;
}
```
### Remove React + Fuse.js in favor of Pagefind search
In previous versions, React.js and Fuse.js were used for search functionality and OG image generation. In AstroPaper v5, React.js has been removed and replaced with [Pagefind](https://pagefind.app/), a static site search tool.
The search experience is almost identical to previous versions, but now all contents, not just titles and descriptions, are indexed and searchable, thanks to Pagefind.
The idea of using Pagefind in dev mode was inspired by [this blog post](https://chrispennington.blog/blog/pagefind-static-search-for-astro-sites/).
### Updated import alias
The import alias has been updated from `@directory` to `@/directory`, which means you now have to import like this:
```astro
---
import { slugifyStr } from "@/utils/slugify";
import IconHash from "@/assets/icons/IconHash.svg";
---
```
### Move to `pnpm`
AstroPaper has switched from `npm` to `pnpm`, which offers faster and more efficient package management.
### Replace icons/svg with Astro's Svg Component
AstroPaper v5 replaces inline SVGs with Astros experimental [SVG Component](https://docs.astro.build/en/reference/experimental-flags/svg/). This update reduces the need for predefined SVG code in the `socialIcons` object, making the codebase cleaner and more maintainable.
### Separate Constants and Config
The project structure has been reorganized. The `src/config.ts` file now only contains the `SITE` object, which holds the main configuration for the project. All constants, such as `LOCALE`, `SOCIALS`, and `SHARE_LINKS`, have been moved to the `src/constants.ts` file.
## Other notable changes
- The blog posts directory has been updated from `src/content/blog/` to `src/data/blog/`.
- Conllection definitions file (`src/content/config.ts`) is now replaced with `src/content.config.ts`.
- Various dependencies have been upgraded for improved performance and security.
- Removed `IBM Plex Mono` font and switched to the default system mono font.
- The `Go back` button logic has been updated. Now, instead of triggering the browser's history API, AstroPaper v5 uses the browser session to temporarily store the back URL. If no back URL exists in the session, it will redirect to the homepage.
- There are some minor styles and layout changes as well.
## Outtro
AstroPaper v5 brings many changes, but the core experience remains the same. Enjoy a smoother, more efficient blogging platform while keeping the clean and minimal design that AstroPaper is known for!
Feel free to explore the changes and share your thoughts. As always, thank you for your support!
If you enjoy this theme, please consider starring the repo. You can also support me via GitHub Sponsors or you can buy me a coffee if you'd like. However, of course, these actions are entirely optional and not required.
Enjoy!
[Sat Naing](https://satnaing.dev/)

View file

@ -1,208 +0,0 @@
---
author: Sat Naing
pubDatetime: 2022-09-23T15:22:00Z
modDatetime: 2025-03-22T06:25:46.734Z
title: Adding new posts in AstroPaper theme
slug: adding-new-posts-in-astropaper-theme
featured: true
draft: false
tags:
- docs
description:
Some rules & recommendations for creating or adding new posts using AstroPaper
theme.
---
Here are some rules/recommendations, tips & ticks for creating new posts in AstroPaper blog theme.
<figure>
<img
src="https://images.pexels.com/photos/159618/still-life-school-retro-ink-159618.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
alt="Free Classic wooden desk with writing materials, vintage clock, and a leather bag. Stock Photo"
/>
<figcaption class="text-center">
Photo by <a href="https://www.pexels.com/photo/brown-wooden-desk-159618/">Pixabay</a>
</figcaption>
</figure>
## Table of contents
## Creating a Blog Post
To write a new blog post, create a markdown file inside the `src/data/blog/` directory.
> Prior to AstroPaper v5.1.0, all blog posts had to be in `src/data/blog/`, meaning you couldn't organize them into subdirectories.
Starting from AstroPaper v5.1.0, you can now organize blog posts into subdirectories, making it easier to manage your content.
For example, if you want to group posts under `2025`, you can place them in `src/data/blog/2025/`. This also affects the post URL, so `src/data/blog/2025/example-post.md` will be available at `/posts/2025/example-post`.
If you dont want subdirectories to affect the post URL, just prefix the folder name with an underscore `_`.
```bash
# Example: blog post structure and URLs
src/data/blog/very-first-post.md -> mysite.com/posts/very-first-post
src/data/blog/2025/example-post.md -> mysite.com/posts/2025/example-post
src/data/blog/_2026/another-post.md -> mysite.com/posts/another-post
src/data/blog/docs/_legacy/how-to.md -> mysite.com/docs/how-to
src/data/blog/Example Dir/Dummy Post.md -> mysite.com/example-dir/dummy-post
```
> 💡 Tip: You can override a blog posts slug in the frontmatter as well. See the next section for more details.
If the subdirectory URL doesnt appear in the build output, remove node_modules, reinstall packages, and then rebuild.
## Frontmatter
Frontmatter is the main place to store some important information about the blog post (article). Frontmatter lies at the top of the article and is written in YAML format. Read more about frontmatter and its usage in [astro documentation](https://docs.astro.build/en/guides/markdown-content/).
Here is the list of frontmatter property for each post.
| Property | Description | Remark |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
| **_title_** | Title of the post. (h1) | required<sup>\*</sup> |
| **_description_** | Description of the post. Used in post excerpt and site description of the post. | required<sup>\*</sup> |
| **_pubDatetime_** | Published datetime in ISO 8601 format. | required<sup>\*</sup> |
| **_modDatetime_** | Modified datetime in ISO 8601 format. (only add this property when a blog post is modified) | optional |
| **_author_** | Author of the post. | default = SITE.author |
| **_slug_** | Slug for the post. This field is optional. | default = slugified file name |
| **_featured_** | Whether or not display this post in featured section of home page | default = false |
| **_draft_** | Mark this post 'unpublished'. | default = false |
| **_tags_** | Related keywords for this post. Written in array yaml format. | default = others |
| **_ogImage_** | OG image of the post. Useful for social media sharing and SEO. This can be a remote URL or an image path relative to current folder. | default = `SITE.ogImage` or generated OG image |
| **_canonicalURL_** | Canonical URL (absolute), in case the article already exists on other source. | default = `Astro.site` + `Astro.url.pathname` |
| **_hideEditPost_** | Hide editPost button under blog title. This applies only to the current blog post. | default = false |
| **_timezone_** | Specify a timezone in IANA format for the current blog post. This will override the `SITE.timezone` config for the current blog post. | default = `SITE.timezone` |
> Tip! You can get ISO 8601 datetime by running `new Date().toISOString()` in the console. Make sure you remove quotes though.
Only `title`, `description` and `pubDatetime` fields in frontmatter must be specified.
Title and description (excerpt) are important for search engine optimization (SEO) and thus AstroPaper encourages to include these in blog posts.
`slug` is the unique identifier of the url. Thus, `slug` must be unique and different from other posts. The whitespace of `slug` should to be separated with `-` or `_` but `-` is recommended. Slug is automatically generated using the blog post file name. However, you can define your `slug` as a frontmatter in your blog post.
For example, if the blog file name is `adding-new-post.md` and you don't specify the slug in your frontmatter, Astro will automatically create a slug for the blog post using the file name. Thus, the slug will be `adding-new-post`. But if you specify the `slug` in the frontmatter, this will override the default slug. You can read more about this in [Astro Docs](https://docs.astro.build/en/guides/content-collections/#defining-custom-slugs).
If you omit `tags` in a blog post (in other words, if no tag is specified), the default tag `others` will be used as a tag for that post. You can set the default tag in the `/src/content/config.ts` file.
```ts
// src/content/config.ts
export const blogSchema = z.object({
// ---
draft: z.boolean().optional(),
tags: z.array(z.string()).default(["others"]), // replace "others" with whatever you want
// ---
});
```
### Sample Frontmatter
Here is the sample frontmatter for a post.
```yaml
# src/content/blog/sample-post.md
---
title: The title of the post
author: your name
pubDatetime: 2022-09-21T05:17:19Z
slug: the-title-of-the-post
featured: true
draft: false
tags:
- some
- example
- tags
ogImage: ../../assets/images/example.png # src/assets/images/example.png
# ogImage: "https://example.org/remote-image.png" # remote URL
description: This is the example description of the example post.
canonicalURL: https://example.org/my-article-was-already-posted-here
---
```
## Adding table of contents
By default, a post (article) does not include any table of contents (toc). To include toc, you have to specify it in a specific way.
Write `Table of contents` in h2 format (## in markdown) and place it where you want it to be appeared on the post.
For instance, if you want to place your table of contents just under the intro paragraph (like I usually do), you can do that in the following way.
```md
---
# some frontmatter
---
Here are some recommendations, tips & ticks for creating new posts in AstroPaper blog theme.
## Table of contents
<!-- the rest of the post -->
```
## Headings
There's one thing to note about headings. The AstroPaper blog posts use title (title in the frontmatter) as the main heading of the post. Therefore, the rest of the heading in the post should be using h2 \~ h6.
This rule is not mandatory, but highly recommended for visual, accessibility and SEO purposes.
## Storing Images for Blog Content
Here are two methods for storing images and displaying them inside a markdown file.
> Note! If it's a requirement to style optimized images in markdown you should [use MDX](https://docs.astro.build/en/guides/images/#images-in-mdx-files).
### Inside `src/assets/` directory (recommended)
You can store images inside `src/assets/` directory. These images will be automatically optimized by Astro through [Image Service API](https://docs.astro.build/en/reference/image-service-reference/).
You can use relative path or alias path (`@/assets/`) to serve these images.
Example: Suppose you want to display `example.jpg` whose path is `/src/assets/images/example.jpg`.
```md
![something](@/assets/images/example.jpg)
<!-- OR -->
![something](../../assets/images/example.jpg)
<!-- Using img tag or Image component won't work ❌ -->
<img src="@/assets/images/example.jpg" alt="something">
<!-- ^^ This is wrong -->
```
> Technically, you can store images inside any directory under `src`. In here, `src/assets` is just a recommendation.
### Inside `public` directory
You can store images inside the `public` directory. Keep in mind that images stored in the `public` directory remain untouched by Astro, meaning they will be unoptimized and you need to handle image optimization by yourself.
For these images, you should use an absolute path; and these images can be displayed using [markdown annotation](https://www.markdownguide.org/basic-syntax/#images-1) or [HTML img tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img).
Example: Assume `example.jpg` is located at `/public/assets/images/example.jpg`.
```md
![something](/assets/images/example.jpg)
<!-- OR -->
<img src="/assets/images/example.jpg" alt="something">
```
## Bonus
### Image compression
When you put images in the blog post (especially for images under `public` directory), it is recommended that the image is compressed. This will affect the overall performance of the website.
My recommendation for image compression sites.
- [TinyPng](https://tinypng.com/)
- [TinyJPG](https://tinyjpg.com/)
### OG Image
The default OG image will be placed if a post does not specify the OG image. Though not required, OG image related to the post should be specify in the frontmatter. The recommended size for OG image is **_1200 X 640_** px.
> Since AstroPaper v1.4.0, OG images will be generated automatically if not specified. Check out [the announcement](https://astro-paper.pages.dev/posts/dynamic-og-image-generation-in-astropaper-blog-posts/).

View file

@ -0,0 +1,11 @@
---
author: Sat Naing
pubDatetime: 2022-09-23T15:22:00Z
modDatetime: 2025-03-22T06:25:46.734Z
title: Creating my blog
featured: true
draft: false
description: ""
---
Pourquoi j'écris en anglais putain

View file

@ -1,132 +0,0 @@
---
author: Sat Naing
pubDatetime: 2022-09-25T15:20:35Z
title: Customizing AstroPaper theme color schemes
featured: false
draft: false
tags:
- color-schemes
- docs
description:
How you can enable/disable light & dark mode; and customize color schemes
of AstroPaper theme.
---
This post will explain how you can enable/disable light & dark mode for the website. Moreover, you'll learn how you can customize color schemes of the entire website.
## Table of contents
## Enable/disable light & dark mode
AstroPaper theme will include light and dark mode by default. In other words, there will be two color schemes\_ one for light mode and another for dark mode. This default behavior can be disabled in SITE configuration object of the `src/config.ts` file.
```js
// file: src/config.ts
export const SITE = {
website: "https://astro-paper.pages.dev/",
author: "Sat Naing",
desc: "A minimal, responsive and SEO-friendly Astro blog theme.",
title: "AstroPaper",
ogImage: "astropaper-og.jpg",
lightAndDarkMode: true, // true by default
postPerPage: 3,
};
```
To disable `light & dark mode` set `SITE.lightAndDarkMode` to `false`.
## Choose primary color scheme
By default, if we disable `SITE.lightAndDarkMode`, we will only get system's prefers-color-scheme.
Thus, to choose primary color scheme instead of prefers-color-scheme, we have to set color scheme in the primaryColorScheme variable inside `public/toggle-theme.js`.
```js
/* file: public/toggle-theme.js */
const primaryColorScheme = ""; // "light" | "dark"
// Get theme data from local storage
const currentTheme = localStorage.getItem("theme");
// other codes etc...
```
The **primaryColorScheme** variable can hold two values\_ `"light"`, `"dark"`. You can leave the empty string (default) if you don't want to specify the primary color scheme.
- `""` - system's prefers-color-scheme. (default)
- `"light"` - use light mode as primary color scheme.
- `"dark"` - use dark mode as primary color scheme.
<details><summary>Why 'primaryColorScheme' is not inside config.ts?</summary>
> To avoid color flickering on page reload, we have to place the toggle-switch JavaScript codes as early as possible when the page loads. It solves the problem of flickering, but as a trade-off, we cannot use ESM imports anymore.
[Click here](https://docs.astro.build/en/reference/directives-reference/#isinline) to know more about Astro's `is:inline` script.
</details>
## Customize color schemes
Both light & dark color schemes of AstroPaper theme can be customized. You can do this in `src/styles/base.css` file.
```css
/* file: src/styles/base.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root,
html[data-theme="light"] {
--color-fill: 251, 254, 251;
--color-text-base: 40, 39, 40;
--color-accent: 0, 108, 172;
--color-card: 230, 230, 230;
--color-card-muted: 205, 205, 205;
--color-border: 236, 233, 233;
}
html[data-theme="dark"] {
--color-fill: 47, 55, 65;
--color-text-base: 230, 230, 230;
--color-accent: 26, 217, 217;
--color-card: 63, 75, 90;
--color-card-muted: 89, 107, 129;
--color-border: 59, 70, 85;
}
/* other styles */
}
```
In AstroPaper theme, `:root` and `html[data-theme="light"]` selectors are used as the light color scheme and `html[data-theme="dark"]` is used the dark color scheme. If you want to customize your custom color scheme, you have to specify your light color scheme inside `:root`,`html[data-theme="light"]` and dark color scheme inside `html[data-theme="dark"]`.
Colors are declared in CSS custom property (CSS Variable) notation. Color property values are written in rgb values. (Note: instead of `rgb(40, 39, 40)`, only specify `40, 39, 40`)
Here is the detail explanation of color properties.
| Color Property | Definition & Usage |
| -------------------- | ---------------------------------------------------------- |
| `--color-fill` | Primary color of the website. Usually the main background. |
| `--color-text-base` | Secondary color of the website. Usually the text color. |
| `--color-accent` | Accent color of the website. Link color, hover color etc. |
| `--color-card` | Card, scrollbar and code background color (like `this`). |
| `--color-card-muted` | Card and scrollbar background color for hover state etc. |
| `--color-border` | Border color. Especially used in horizontal row (hr) |
Here is an example of changing the light color scheme.
```css
@layer base {
/* lobster color scheme */
:root,
html[data-theme="light"] {
--color-fill: 246, 238, 225;
--color-text-base: 1, 44, 86;
--color-accent: 225, 74, 57;
--color-card: 220, 152, 145;
--color-card-muted: 233, 119, 106;
--color-border: 220, 152, 145;
}
}
```
> Check out some [predefined color schemes](https://astro-paper.pages.dev/posts/predefined-color-schemes/) AstroPaper has already crafted for you.

View file

@ -1,97 +0,0 @@
---
author: Sat Naing
pubDatetime: 2022-12-28T04:59:04.866Z
modDatetime: 2025-03-12T13:39:20.763Z
title: Dynamic OG image generation in AstroPaper blog posts
slug: dynamic-og-image-generation-in-astropaper-blog-posts
featured: false
draft: false
tags:
- docs
- release
description: New feature in AstroPaper v1.4.0, introducing dynamic OG image generation for blog posts.
---
New feature in AstroPaper v1.4.0, introducing dynamic OG image generation for blog posts.
## Table of contents
## Intro
OG images (aka Social Images) play an important role in social media engagements. In case you don't know what OG image means, it is an image displayed whenever we share our website URL on social media such as Facebook, Discord etc.
> The Social Image used for Twitter is technically not called OG image. However, in this post, I'll be using the term OG image for all types of Social Images.
## Default/Static OG image (the old way)
AstroPaper already provided a way to add an OG image to a blog post. The author can specify the OG image in the frontmatter `ogImage`. Even when the author doesn't define the OG image in the frontmatter, the default OG image will be used as a fallback (in this case `public/astropaper-og.jpg`). But the problem is that the default OG image is static, which means every blog post that does not include an OG image in the frontmatter will always use the same default OG image despite each post title/content being different from others.
## Dynamic OG Image
Generating a dynamic OG image for each post allows the author to avoid specifying an OG image for every single blog post. Besides, this will prevent the fallback OG image from being identical to all blog posts.
In AstroPaper v1.4.0, Vercel's [Satori](https://github.com/vercel/satori) package is used for dynamic OG image generation.
Dynamic OG images will be generated at build time for blog posts that
- don't include OG image in the frontmatter
- are not marked as draft.
## Anatomy of AstroPaper dynamic OG image
Dynamic OG image of AstroPaper includes _the blog post title_, _author name_ and _site title_. Author name and site title will be retrieved via `SITE.author` and `SITE.title` of **"src/config.ts"** file. The title is generated from the blog post frontmatter `title`.
![Example Dynamic OG Image link](https://user-images.githubusercontent.com/53733092/209704501-e9c2236a-3f4d-4c67-bab3-025aebd63382.png)
### Issue Non-Latin Characters
Titles with non-latin characters won't display properly out of the box. To resolve this, we have to replace `fontsConfig` inside `loadGoogleFont.ts` with your preferred font.
```ts
// file: loadGoogleFont.ts
async function loadGoogleFonts(
text: string
): Promise<
Array<{ name: string; data: ArrayBuffer; weight: number; style: string }>
> {
const fontsConfig = [
{
name: "Noto Sans JP",
font: "Noto+Sans+JP",
weight: 400,
style: "normal",
},
{
name: "Noto Sans JP",
font: "Noto+Sans+JP:wght@700",
weight: 700,
style: "normal",
},
{ name: "Noto Sans", font: "Noto+Sans", weight: 400, style: "normal" },
{
name: "Noto Sans",
font: "Noto+Sans:wght@700",
weight: 700,
style: "normal",
},
];
// other codes
}
```
> Check out [this PR](https://github.com/satnaing/astro-paper/pull/318) for more info.
## Trade-off
While this is a nice feature to have, there's a trade-off. Each OG image takes roughly one second to generate. This might not be noticeable at first, but as the number of blog posts grows, you might want to disable this feature. Since every OG image takes time to generate, having many of them will increase the build time linearly.
For example: If one OG image takes one second to generate, then 60 images will take around one minute, and 600 images will take approximately 10 minutes. This can significantly impact build times as your content scales.
Related issue: [#428](https://github.com/satnaing/astro-paper/issues/428)
## Limitations
At the time of writing this, [Satori](https://github.com/vercel/satori) is fairly new and has not reached major release yet. So, there are still some limitations to this dynamic OG image feature.
- Besides, RTL languages are not supported yet.
- [Using emoji](https://github.com/vercel/satori#emojis) in the title might be a little bit tricky.

View file

@ -1,21 +0,0 @@
---
title: Example Draft Post
author: Sat Naing
pubDatetime: 2022-06-06T04:06:31Z
slug: example-draft-post
featured: false
draft: true
tags:
- TypeScript
- Astro
description:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Praesent elementum facilisis leo vel
fringilla est
---
Users cannot see this post because it is in draft.
## Motivation
rec 1

View file

@ -1,105 +0,0 @@
---
title: How Do I Develop My Portfolio Website & Blog
author: Sat Naing
pubDatetime: 2022-03-25T16:55:12.000+00:00
slug: how-do-i-develop-my-portfolio-and-blog
featured: false
draft: false
tags:
- NextJS
- TailwindCSS
- HeadlessCMS
- Blog
description:
"EXAMPLE POST: My experience about developing my first portfolio website and a blog
using NextJS and a headless CMS."
timezone: "Asia/Yangon"
---
> This article is originally from my [blog post](https://satnaing.dev/blog/posts/how-do-i-develop-my-portfolio-and-blog). I put this article to demonstrate how you can write blog posts/articles using AstroPaper theme.
My experience about developing my first portfolio website and a blog using NextJS and a headless CMS.
![Building portfolio](https://satnaing.dev/_ipx/w_2048,q_75/https%3A%2F%2Fres.cloudinary.com%2Fnoezectz%2Fimage%2Fupload%2Fv1653050141%2FSatNaing%2Fblog_at_cafe_ei1wf4.jpg?url=https%3A%2F%2Fres.cloudinary.com%2Fnoezectz%2Fimage%2Fupload%2Fv1653050141%2FSatNaing%2Fblog_at_cafe_ei1wf4.jpg&w=2048&q=75)
## Motivation
I've been always thinking about launching my own website with my custom domain name (**satnaing.dev**) since my college student life. But that never happened until this project. I've done several projects and works about web application development but I didn't make an effort to do this.
So, "what about blog?" you may ask. Yeah, blog also has been in my project list for some time. I always wanted to make a blog project using some of the latest technologies. However, I've been busy with my works and other projects so that blog project has never been started.
In these days, I tend to develop my own projects with the focus in good quality rather than quantity. After the project is done, I usually put a proper readme file in the Github repo. But Github repo readme is only suitable for technical aspects (this is just my thought). I want to write down my experiences and challenges. Thus, I decided to make my own blog. Plus, at this point, I have decent experiences and confidence to develop this project.
## Tech Stack
For the front-end, I wanted to use [React](https://reactjs.org/ "React Official Website"). But React alone is not good enough for SEO; and I did have to consider many factors like routing, image optimization etc. So, I chose [NextJS](https://nextjs.org/ "NextJS Official Website") as my main front-end stack. And of course TypeScript for type checking. (It's said that you'll love TypeScript when you're used to it 😉)
For styling, I use [TailwindCSS](https://tailwindcss.com/ "Tailwind CSS Official Website"). This is because I love developer experience that Tailwind gives and it has a lot of flexibilities compared to other component UI libraries like MUI or React Bootstrap.
All contents of this project reside within the GitHub repository. All my blog posts (including this one) are written in Markdown file format since I'm very used to with this. But to write Markdown along with its frontmatter effortlessly, I use [Forestry](https://forestry.io/ "Forestry Official Website") headless CMS. It is a git-based CMS that can serve Markdown and other contents. Because of this, I can write my contents either using Markdown or wysiwyg editor. Besides, writing frontmatters with this is a breeze.
Images and assets are uploaded and stored in [Cloudinary](https://cloudinary.com/ "Cloudinary Official Website"). I connect Cloudinary via Forestry and manage them directly in the dashboard.
In conclusion, these are the tech stack I've used for this project.
- Front-end: NextJS (TypeScript)
- Styling: TailwindCSS
- Animations: GSAP
- CMS: Forestry Headless CMS
- Deployment: Vercel
## Features
The following are certain features of my portfolio and blog
### SEO Friendly
The entire project is developed with SEO focus in mind. I've used proper meta tags, descriptions and heading alignments. This website is now indexed by Google.
> You can search this website on google by using keywords like 'sat naing dev'
![searching satnaing.dev on google](https://res.cloudinary.com/noezectz/image/upload/v1648231400/SatNaing/satnaing-on-google_asflq6.png "satnaing.dev is indexed")
Moreover, this website will be displayed well when shared to social media due to properly used meta tags.
![satnaing.dev card layout when shared to Facebook](https://res.cloudinary.com/noezectz/image/upload/v1653106955/SatNaing/satnaing-dev-share-on-facebook_1_zjoehx.png "Card layout when shared to Facebook")
### Dynamic Sitemap
Sitemap plays an important part in SEO. Because of this, every single page of this site should be included in sitemap.xml. I made an auto generated sitemap in my website whenever I create a new content or tags or categories.
### Light & Dark Themes
Due to dark theme trend in recent years, many websites include dark theme out of the box nowadays. Certainly, my website also supports light & dark themes.
### Fully Accessible
This website is fully accessible. You can navigate around by only using keyboard. I put all a11y enhancement best practices like including alt text in all images, no skipping headings, using semantic HTML tags, using aria-attributes properly.
### Search box, Categories & Tags
All blog contents can be searched by search box. Moreover, contents can be filtered by categories and tags. In this way, blog readers can search and read what they really want.
### Performance and Lighthouse Score
This website got very good performance and lighthouse score thanks to proper development and best practices. Here's the lighthouse score for this website.
![satnaing.dev Lighthouse score](https://user-images.githubusercontent.com/53733092/159957822-7082e459-11e9-4616-8f1e-49d0881f7cbb.png "satnaing.dev Lighthouse score")
### Animations
Initially I used [Framer Motion](https://www.framer.com/motion/ "Framer Motion") to add animations and micro interactions for this website. However, when I tried to use some complex animations and parallax effects, I found it inconvenient to integrate with Framer Motion (Maybe I'm not very good at and used to working with it). Hence, I decided to use [GSAP](https://greensock.com/ "GSAP Animation Library") for all of my animations. It is one of the most popular animation library and it is capable of doing complex and advanced animations. You can see animations and micro interactions on pretty much every page of this website.
![animations at satnaing.dev](https://res.cloudinary.com/noezectz/image/upload/v1653108324/SatNaing/ezgif.com-gif-maker_2_hehtlm.gif "satnaing.dev website")
## Outro
In conclusion, this project gives me a lot of experience and confidence about developing blog site (SSG). Now, I have gained knowledge of git-based CMS and how it interacts with NextJS. I've also learned about SEO, dynamic sitemap generation and indexing Google procedures. I will make better projects in the future. So, stay tuned! ✌🏻
And... last but not least, I would like to say 'thanks' to my friend [Swann Fevian Kyaw](https://www.facebook.com/bon.zai.3910 "Swann Fevian Kyaw's Facebook Account") (@[ToonHa](https://www.facebook.com/ToonHa-102639465752883 "ToonHa Facebook Page")) who has drawn a beautiful illustration for my hero section of the website.
## Project Links
- Website: [https://satnaing.dev/](https://satnaing.dev/ "https://satnaing.dev/")
- Blog: [https://satnaing.dev/blog](https://satnaing.dev/blog "https://satnaing.dev/blog")
- Repo: [https://github.com/satnaing/my-portfolio](https://github.com/satnaing/my-portfolio "https://github.com/satnaing/my-portfolio")

View file

@ -1,208 +0,0 @@
---
title: Tailwind Typography Plugin
author: Sat Naing
pubDatetime: 2022-07-05T02:05:51Z
featured: false
draft: false
tags:
- TypeScript
- Astro
description: "EXAMPLE POST: About Tailwind Typography Plugin and how you can use it effectively."
---
> This article is from [TailwindLabs](https://tailwindcss-typography.vercel.app/). I put this article to demonstrate how you can write blog posts/articles using AstroPaper theme.
By default, Tailwind removes all of the default browser styling from paragraphs, headings, lists and more. This ends up being really useful for building application UIs because you spend less time undoing user-agent styles, but when you _really are_ just trying to style some content that came from a rich-text editor in a CMS or a markdown file, it can be surprising and unintuitive.
We get lots of complaints about it actually, with people regularly asking us things like:
> Why is Tailwind removing the default styles on my `h1` elements? How do I disable this? What do you mean I lose all the other base styles too?
> We hear you, but we're not convinced that simply disabling our base styles is what you really want. You don't want to have to remove annoying margins every time you use a `p` element in a piece of your dashboard UI. And I doubt you really want your blog posts to use the user-agent styles either — you want them to look _awesome_, not awful.
The `@tailwindcss/typography` plugin is our attempt to give you what you _actually_ want, without any of the downsides of doing something stupid like disabling our base styles.
It adds a new `prose` class that you can slap on any block of vanilla HTML content and turn it into a beautiful, well-formatted document:
```html
<article class="prose">
<h1>Garlic bread with cheese: What the science tells us</h1>
<p>
For years parents have espoused the health benefits of eating garlic bread
with cheese to their children, with the food earning such an iconic status
in our culture that kids will often dress up as warm, cheesy loaf for
Halloween.
</p>
<p>
But a recent study shows that the celebrated appetizer may be linked to a
series of rabies cases springing up around the country.
</p>
<!-- ... -->
</article>
```
For more information about how to use the plugin and the features it includes, [read the documentation](https://github.com/tailwindcss/typography/blob/master/README.md).
---
## What to expect from here on out
What follows from here is just a bunch of absolute nonsense I've written to dogfood the plugin itself. It includes every sensible typographic element I could think of, like **bold text**, unordered lists, ordered lists, code blocks, block quotes, _and even italics_.
It's important to cover all of these use cases for a few reasons:
1. We want everything to look good out of the box.
2. Really just the first reason, that's the whole point of the plugin.
3. Here's a third pretend reason though a list with three items looks more realistic than a list with two items.
Now we're going to try out another header style.
### Typography should be easy
So that's a header for you — with any luck if we've done our job correctly that will look pretty reasonable.
Something a wise person once told me about typography is:
> Typography is pretty important if you don't want your stuff to look like trash. Make it good then it won't be bad.
> It's probably important that images look okay here by default as well:
<figure>
<img
src="https://images.unsplash.com/photo-1556740758-90de374c12ad?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1000&q=80"
alt=""
/>
<figcaption>
Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of
classical Latin literature from 45 BC, making it over 2000 years old.
</figcaption>
</figure>
Now I'm going to show you an example of an unordered list to make sure that looks good, too:
- So here is the first item in this list.
- In this example we're keeping the items short.
- Later, we'll use longer, more complex list items.
And that's the end of this section.
## What if we stack headings?
### We should make sure that looks good, too.
Sometimes you have headings directly underneath each other. In those cases you often have to undo the top margin on the second heading because it usually looks better for the headings to be closer together than a paragraph followed by a heading should be.
### When a heading comes after a paragraph …
When a heading comes after a paragraph, we need a bit more space, like I already mentioned above. Now let's see what a more complex list would look like.
- **I often do this thing where list items have headings.**
For some reason I think this looks cool which is unfortunate because it's pretty annoying to get the styles right.
I often have two or three paragraphs in these list items, too, so the hard part is getting the spacing between the paragraphs, list item heading, and separate list items to all make sense. Pretty tough honestly, you could make a strong argument that you just shouldn't write this way.
- **Since this is a list, I need at least two items.**
I explained what I'm doing already in the previous list item, but a list wouldn't be a list if it only had one item, and we really want this to look realistic. That's why I've added this second list item so I actually have something to look at when writing the styles.
- **It's not a bad idea to add a third item either.**
I think it probably would've been fine to just use two items but three is definitely not worse, and since I seem to be having no trouble making up arbitrary things to type, I might as well include it.
After this sort of list I usually have a closing statement or paragraph, because it kinda looks weird jumping right to a heading.
## Code should look okay by default.
I think most people are going to use [highlight.js](https://highlightjs.org/) or [Prism](https://prismjs.com/) or something if they want to style their code blocks but it wouldn't hurt to make them look _okay_ out of the box, even with no syntax highlighting.
Here's what a default `tailwind.config.js` file looks like at the time of writing:
```js
module.exports = {
purge: [],
theme: {
extend: {},
},
variants: {},
plugins: [],
};
```
Hopefully that looks good enough to you.
### What about nested lists?
Nested lists basically always look bad which is why editors like Medium don't even let you do it, but I guess since some of you goofballs are going to do it we have to carry the burden of at least making it work.
1. **Nested lists are rarely a good idea.**
- You might feel like you are being really "organized" or something but you are just creating a gross shape on the screen that is hard to read.
- Nested navigation in UIs is a bad idea too, keep things as flat as possible.
- Nesting tons of folders in your source code is also not helpful.
2. **Since we need to have more items, here's another one.**
- I'm not sure if we'll bother styling more than two levels deep.
- Two is already too much, three is guaranteed to be a bad idea.
- If you nest four levels deep you belong in prison.
3. **Two items isn't really a list, three is good though.**
- Again please don't nest lists if you want people to actually read your content.
- Nobody wants to look at this.
- I'm upset that we even have to bother styling this.
The most annoying thing about lists in Markdown is that `<li>` elements aren't given a child `<p>` tag unless there are multiple paragraphs in the list item. That means I have to worry about styling that annoying situation too.
- **For example, here's another nested list.**
But this time with a second paragraph.
- These list items won't have `<p>` tags
- Because they are only one line each
- **But in this second top-level list item, they will.**
This is especially annoying because of the spacing on this paragraph.
- As you can see here, because I've added a second line, this list item now has a `<p>` tag.
This is the second line I'm talking about by the way.
- Finally here's another list item so it's more like a list.
- A closing list item, but with no nested list, because why not?
And finally a sentence to close off this section.
## There are other elements we need to style
I almost forgot to mention links, like [this link to the Tailwind CSS website](https://tailwindcss.com). We almost made them blue but that's so yesterday, so we went with dark gray, feels edgier.
We even included table styles, check it out:
| Wrestler | Origin | Finisher |
| ----------------------- | ------------ | ------------------ |
| Bret "The Hitman" Hart | Calgary, AB | Sharpshooter |
| Stone Cold Steve Austin | Austin, TX | Stone Cold Stunner |
| Randy Savage | Sarasota, FL | Elbow Drop |
| Vader | Boulder, CO | Vader Bomb |
| Razor Ramon | Chuluota, FL | Razor's Edge |
We also need to make sure inline code looks good, like if I wanted to talk about `<span>` elements or tell you the good news about `@tailwindcss/typography`.
### Sometimes I even use `code` in headings
Even though it's probably a bad idea, and historically I've had a hard time making it look good. This _"wrap the code blocks in backticks"_ trick works pretty well though really.
Another thing I've done in the past is put a `code` tag inside of a link, like if I wanted to tell you about the [`tailwindcss/docs`](https://github.com/tailwindcss/docs) repository. I don't love that there is an underline below the backticks but it is absolutely not worth the madness it would require to avoid it.
#### We haven't used an `h4` yet
But now we have. Please don't use `h5` or `h6` in your content, Medium only supports two heading levels for a reason, you animals. I honestly considered using a `before` pseudo-element to scream at you if you use an `h5` or `h6`.
We don't style them at all out of the box because `h4` elements are already so small that they are the same size as the body copy. What are we supposed to do with an `h5`, make it _smaller_ than the body copy? No thanks.
### We still need to think about stacked headings though.
#### Let's make sure we don't screw that up with `h4` elements, either.
Phew, with any luck we have styled the headings above this text and they look pretty good.
Let's add a closing paragraph here so things end with a decently sized block of text. I can't explain why I want things to end that way but I have to assume it's because I think things will look weird or unbalanced if there is a heading too close to the end of the document.
What I've written here is probably long enough, but adding this final sentence can't hurt.

View file

@ -1,89 +0,0 @@
---
title: How Do I Develop My Terminal Portfolio Website with React
author: Sat Naing
pubDatetime: 2022-06-09T03:42:51Z
slug: how-do-i-develop-my-terminal-portfolio-website-with-react
featured: false
draft: false
tags:
- JavaScript
- ReactJS
- ContextAPI
- Styled-Components
- TypeScript
description:
"EXAMPLE POST: Developing a terminal-like website using ReactJS, TypeScript and Styled-Components.
Includes features like autocomplete, multiple themes, command hints etc."
timezone: "Asia/Yangon"
---
> This article is originally from my [blog post](https://satnaing.dev/blog/posts/how-do-i-develop-my-terminal-portfolio-website-with-react). I put this article to demonstrate how you can write blog posts/articles using AstroPaper theme.
Developing a terminal-like website using ReactJS, TypeScript and Styled-Components. Includes features like autocomplete, multiple themes, command hints etc.
![Sat Naing's Terminal Portfolio](https://satnaing.dev/_ipx/w_2048,q_75/https%3A%2F%2Fres.cloudinary.com%2Fnoezectz%2Fimage%2Fupload%2Fv1654754125%2FSatNaing%2Fterminal-screenshot_gu3kkc.png?url=https%3A%2F%2Fres.cloudinary.com%2Fnoezectz%2Fimage%2Fupload%2Fv1654754125%2FSatNaing%2Fterminal-screenshot_gu3kkc.png&w=2048&q=75)
## Table of contents
## Intro
Recently, I've developed and published my portfolio + a blog. Im glad I got some good feedback for it. Today, I want to introduce my new terminal-like portfolio website. It is developed using ReactJS, TypeScript. I got this idea from CodePen and YouTube.
## Tech Stack
This project is a frontend project without any backend codes. The UI/UX part is designed in Figma. For the frontend user-interface, I chose React over pain JavaScript and NextJS. Why?
- Firstly, I want to write declarative code. Managing HTML DOM using JavaScript imperatively is really tedious.
- Secondly, because it is React!!! It is fast, and reliable.
- Lastly, I dont need much of the SEO features, routing and image optimization provided by NextJS.
And of course there's TypeScript for type checking.
For styling, I took a different approach than what I usually do. Instead of choosing Pure CSS, Sass, or Utility CSS Framework like TailwindCSS, I chose the CSS-in-JS way (Styled-Components). Although Ive known about Styled-Components for some time, Ive never tried it out. So, the writing style and structures of Styled-Components in this project may not be very organized or very good.
This project doesnt need very complex state management. I just use ContextAPI in this project for multiple theming and to avoid prop drilling.
Heres a quick recap for the tech stack.
- Frontend: [ReactJS](https://reactjs.org/ "React Website"), [TypeScript](https://www.typescriptlang.org/ "TypeScript Website")
- Styling: [Styled-Components](https://styled-components.com/ "Styled-Components Website")
- UI/UX: [Figma](https://figma.com/ "Figma Website")
- State Management: [ContextAPI](https://reactjs.org/docs/context.html "React ContextAPI")
- Deployment: [Netlify](https://www.netlify.com/ "Netlify Website")
## Features
Here are some features of the project.
### Multiple Themes
Users can change multiple themes. At the time of writing this post, there are 5 themes; and more themes will probably be added in the future. The selected theme is saved in local storage so that the theme wont change on page refresh.
![Setting different theme](https://i.ibb.co/fSTCnWB/terminal-portfolio-multiple-themes.gif)
### Command-line Completion
To look and feel as close to the actual terminal as possible, I put a command-line completion feature which auto fills in partially typed commands by simply pressing Tab or Ctrl + i.
![Demonstrating command-line completion](https://i.ibb.co/CQTGGLF/terminal-autocomplete.gif)
### Previous Commands
Users can go back to the previous commands or navigate the previously typed commands by pressing Up & Down Arrows.
![Going back to previous commands with UP Arrow](https://i.ibb.co/vD1pSRv/terminal-up-down.gif)
### View/Clear Command History
previously typed commands can be viewed by typing history in the command line. All the command history and terminal screen can be wiped out by typing clear or pressing Ctrl + l.
![Clearing the terminal with 'clear' or 'Ctrl + L' command](https://i.ibb.co/SJBy8Rr/terminal-clear.gif)
## Outro
This is a really fun project, and one special part of this project is I had to focus on logic rather than user-interface (even though this is kind of a frontend project).
## Project Links
- Website: [https://terminal.satnaing.dev/](https://terminal.satnaing.dev/ "https://terminal.satnaing.dev/")
- Repo: [https://github.com/satnaing/terminal-portfolio](https://github.com/satnaing/terminal-portfolio "https://github.com/satnaing/terminal-portfolio")

View file

@ -1,154 +0,0 @@
---
author: Alberto Perdomo
pubDatetime: 2024-09-08T20:58:52.737Z
modDatetime: 2025-03-22T09:25:46.734Z
title: How to add LaTeX Equations in Astro blog posts
tags:
- docs
description: Learn how to add LaTeX equations in Astro blog posts using Markdown, KaTeX, and remark/rehype plugins.
---
This document demonstrates how to use LaTeX equations in your Markdown files for AstroPaper. LaTeX is a powerful typesetting system often used for mathematical and scientific documents.
<figure>
<img
src="https://images.pexels.com/photos/22690748/pexels-photo-22690748/free-photo-of-close-up-of-complicated-equations-written-on-a-blackboard.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2"
alt="Free Close-up of complex equations on a chalkboard, showcasing chemistry and math symbols. Stock Photo"
/>
<figcaption class="text-center">
Photo by <a href="https://www.pexels.com/photo/close-up-of-complicated-equations-written-on-a-blackboard-22690748/">Vitaly Gariev</a>
</figcaption>
</figure>
## Table of contents
## Instructions
In this section, you will find instructions on how to add support for LaTeX in your Markdown files for AstroPaper.
1. Install the necessary remark and rehype plugins by running:
```bash
pnpm install rehype-katex remark-math katex
```
2. Update the Astro configuration (`astro.config.ts`) to use the these plugins:
```ts
// other imports
import remarkMath from "remark-math";
import rehypeKatex from "rehype-katex";
export default defineConfig({
// other configs
markdown: {
remarkPlugins: [
remarkMath, // <- new plugin
remarkToc,
[remarkCollapse, { test: "Table of contents" }],
],
rehypePlugins: [rehypeKatex], // <- new plugin
shikiConfig: {
// For more themes, visit https://shiki.style/themes
themes: { light: "min-light", dark: "night-owl" },
wrap: true,
},
},
// other configs
});
```
3. Import KaTeX CSS in the main layout file `src/layouts/Layout.astro`
```astro
---
import { SITE } from "@config";
// astro code
---
<!doctype html>
<!-- others... -->
<script is:inline src="/toggle-theme.js"></script>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/katex@0.15.2/dist/katex.min.css"
/>
<body>
<slot />
</body>
```
4. As the last step, add a text-color for `katex` in `src/styles/typography.css`.
```css
@plugin '@tailwindcss/typography';
@layer base {
/* other classes */
/* Katex text color */
.prose .katex-display {
@apply text-foreground;
}
/* ===== Code Blocks & Syntax Highlighting ===== */
/* other classes */
}
```
And _voilà_, this setup allows you to write LaTeX equations in your Markdown files, which will be rendered properly when the site is built. Once you do it, the rest of the document will appear rendered correctly.
---
## Inline Equations
Inline equations are written between single dollar signs `$...$`. Here are some examples:
1. The famous mass-energy equivalence formula: `$E = mc^2$`
2. The quadratic formula: `$x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$`
3. Euler's identity: `$e^{i\pi} + 1 = 0$`
---
## Block Equations
For more complex equations or when you want the equation to be displayed on its own line, use double dollar signs `$$...$$`:
The Gaussian integral:
```bash
$$ \int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi} $$
```
The definition of the Riemann zeta function:
```bash
$$ \zeta(s) = \sum_{n=1}^{\infty} \frac{1}{n^s} $$
```
Maxwell's equations in differential form:
```bash
$$
\begin{aligned}
\nabla \cdot \mathbf{E} &= \frac{\rho}{\varepsilon_0} \\
\nabla \cdot \mathbf{B} &= 0 \\
\nabla \times \mathbf{E} &= -\frac{\partial \mathbf{B}}{\partial t} \\
\nabla \times \mathbf{B} &= \mu_0\left(\mathbf{J} + \varepsilon_0 \frac{\partial \mathbf{E}}{\partial t}\right)
\end{aligned}
$$
```
---
## Using Mathematical Symbols
LaTeX provides a wide range of mathematical symbols:
- Greek letters: `$\alpha$`, `$\beta$`, `$\gamma$`, `$\delta$`, `$\epsilon$`, `$\pi$`
- Operators: `$\sum$`, `$\prod$`, `$\int$`, `$\partial$`, `$\nabla$`
- Relations: `$\leq$`, `$\geq$`, `$\approx$`, `$\sim$`, `$\propto$`
- Logical symbols: `$\forall$`, `$\exists$`, `$\neg$`, `$\wedge$`, `$\vee$`

View file

@ -1,184 +0,0 @@
---
author: Sat Naing
pubDatetime: 2022-09-23T04:58:53Z
modDatetime: 2025-03-20T03:15:57.792Z
title: How to configure AstroPaper theme
slug: how-to-configure-astropaper-theme
featured: true
draft: false
tags:
- configuration
- docs
description: How you can make AstroPaper theme absolutely yours.
---
AstroPaper is a highly customizable Astro blog theme. With AstroPaper, you can customize everything according to your personal taste. This article will explain how you can make some customizations easily in the config file.
## Table of contents
## Configuring SITE
The important configurations resides in `src/config.ts` file. Within that file, you'll see the `SITE` object where you can specify your website's main configurations.
During development, it's okay to leave `SITE.website` empty. But in production mode, you should specify your deployed url in `SITE.website` option since this will be used for canonical URL, social card URL etc.. which are important for SEO.
```js
// file: src/config.ts
export const SITE = {
website: "https://astro-paper.pages.dev/", // replace this with your deployed domain
author: "Sat Naing",
profile: "https://satnaing.dev/",
desc: "A minimal, responsive and SEO-friendly Astro blog theme.",
title: "AstroPaper",
ogImage: "astropaper-og.jpg",
lightAndDarkMode: true,
postPerIndex: 4,
postPerPage: 4,
scheduledPostMargin: 15 * 60 * 1000, // 15 minutes
showArchives: true,
showBackButton: true, // show back button in post detail
editPost: {
enabled: true,
text: "Suggest Changes",
url: "https://github.com/satnaing/astro-paper/edit/main/",
},
dynamicOgImage: true, // enable automatic dynamic og-image generation
lang: "en", // html lang code. Set this empty and default will be "en"
timezone: "Asia/Bangkok", // Default global timezone (IANA format) https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
} as const;
```
Here are SITE configuration options
| Options | Description |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `website` | Your deployed website URL |
| `author` | Your name |
| `profile` | Your personal/portfolio website URL which is used for better SEO. Put `null` or empty string `""` if you don't have any. |
| `desc` | Your site description. Useful for SEO and social media sharing. |
| `title` | Your site name |
| `ogImage` | Your default OG image for the site. Useful for social media sharing. OG images can be an external image URL or they can be placed under `/public` directory. |
| `lightAndDarkMode` | Enable or disable `light & dark mode` for the website. If disabled, primary color scheme will be used. This option is enabled by default. |
| `postPerIndex` | The number of posts to be displayed at the home page under `Recent` section. |
| `postPerPage` | You can specify how many posts will be displayed in each posts page. (eg: if you set `SITE.postPerPage` to 3, each page will only show 3 posts per page) |
| `scheduledPostMargin` | In Production mode, posts with a future `pubDatetime` will not be visible. However, if a post's `pubDatetime` is within the next 15 minutes, it will be visible. You can set `scheduledPostMargin` if you don't like the default 15 minutes margin. |
| `showArchives` | Determines whether to display the `Archives` menu (positioned between the `About` and `Search` menus) and its corresponding page on the site. This option is set to `true` by default. |
| `showBackButton` | Determines whether to display the `Go back` button in each blog post. |
| `editPost` | This option allows users to suggest changes to a blog post by providing an edit link under blog post titles. This feature can be disabled by setting `SITE.editPost.enabled` to `false`. |
| `dynamicOgImage` | This option controls whether to [generate dynamic og-image](https://astro-paper.pages.dev/posts/dynamic-og-image-generation-in-astropaper-blog-posts/) if no `ogImage` is specified in the blog post frontmatter. If you have many blog posts, you might want to disable this feature. See the [trade-off](https://astro-paper.pages.dev/posts/dynamic-og-image-generation-in-astropaper-blog-posts/#trade-off) for more details. |
| `lang` | Used as HTML ISO Language code in `<html lang"en">`. Default is `en`. |
| `timezone` | This option allows you to specify your timezone using the [IANA format](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). Setting this ensures consistent timestamps across your localhost and deployed site, eliminating time differences. |
## Configuring logo or title
Prior to AstroPaper v5, you can update your site name/logo in `LOGO_IMAGE` object inside `src/config.ts` file. However, in AstroPaper v5, this option has been removed in favor of Astro's built-in SVG and Image components.
![An arrow pointing at the website logo](https://res.cloudinary.com/noezectz/v1663911318/astro-paper/AstroPaper-logo-config_goff5l.png)
There are 3 options you can do:
### Option 1: SITE title text
This is the easiest option. You just have to update `SITE.title` in `src/config.ts` file.
### Option 2: Astro's SVG component
You might want to use this option if you want to use an SVG logo.
- First add an SVG inside `src/assets` directory. (eg: `src/assets/dummy-logo.svg`)
- Then import that SVG inside `src/components/Header.astro`
```astro
---
// other imports
import DummyLogo from "@/assets/dummy-logo.svg";
---
```
- Finally, replace `{SITE.title}` with imported logo.
```html
<a
href="/"
class="absolute py-1 text-left text-2xl leading-7 font-semibold whitespace-nowrap sm:static"
>
<DummyLogo class="scale-75 dark:invert" />
<!-- {SITE.title} -->
</a>
```
The best part of this approach is that you can customize your SVG styles as needed. In the example above, you can see how the SVG logo color can be inverted in dark mode.
### Option 3: Astro's Image component
If your logo is an image but not SVG, you can use Astro's Image component.
- Add your logo inside `src/assets` directory. (eg: `src/assets/dummy-logo.png`)
- Import `Image` and your logo in `src/components/Header.astro`
```astro
---
// other imports
import { Image } from "astro:assets";
import dummyLogo from "@/assets/dummy-logo.png";
---
```
- Then, replace `{SITE.title}` with imported logo.
```html
<a
href="/"
class="absolute py-1 text-left text-2xl leading-7 font-semibold whitespace-nowrap sm:static"
>
<image src="{dummyLogo}" alt="Dummy Blog" class="dark:invert" />
<!-- {SITE.title} -->
</a>
```
With this approach, you can still adjust your image's appearance using CSS classes. However, this might not always fit what you want. If you need to display different logo images based on light or dark mode, check how light/dark icons are handled inside the `Header.astro` component.
## Configuring social links
You can configure social links in `SOCIALS` object inside `src/constants.ts`.
![An arrow pointing at social link icons](https://github.com/user-attachments/assets/8b895400-d088-442f-881b-02d2443e00cf)
```ts
export const SOCIALS = [
{
name: "Github",
href: "https://github.com/satnaing/astro-paper",
linkTitle: ` ${SITE.title} on Github`,
icon: IconGitHub,
},
{
name: "X",
href: "https://x.com/username",
linkTitle: `${SITE.title} on X`,
icon: IconBrandX,
},
{
name: "LinkedIn",
href: "https://www.linkedin.com/in/username/",
linkTitle: `${SITE.title} on LinkedIn`,
icon: IconLinkedin,
},
{
name: "Mail",
href: "mailto:yourmail@gmail.com",
linkTitle: `Send an email to ${SITE.title}`,
icon: IconMail,
},
] as const;
```
## Configuring share links
You can configure share links in `SHARE_LINKS` object inside `src/constants.ts`.
![An arrow pointing at share link icons](https://github.com/user-attachments/assets/4f930b68-b625-45df-8c41-e076dd2b838e)
## Conclusion
This is the brief specification of how you can customize this theme. You can customize more if you know some coding. For customizing styles, please read [this article](https://astro-paper.pages.dev/posts/customizing-astropaper-theme-color-schemes/). Thanks for reading.✌🏻

View file

@ -1,207 +0,0 @@
---
author: FjellOverflow
pubDatetime: 2024-07-25T11:11:53Z
modDatetime: 2025-03-12T12:28:53Z
title: How to integrate Giscus comments into AstroPaper
slug: how-to-integrate-giscus-comments
featured: false
draft: false
tags:
- astro
- blog
- docs
description: Comment function on a static blog hosted on GitHub Pages with Giscus.
---
Hosting a thin static blog on a platform like [GitHub Pages](https://docs.github.com/en/pages/getting-started-with-github-pages/creating-a-github-pages-site) has numerous advantages, but also takes away some interactivity. Fortunately, [Giscus](https://giscus.app/) exists and offers a way to embed user comments on static sites.
## Table of contents
## How _Giscus_ works
[Giscus uses the GitHub API](https://github.com/giscus/giscus?tab=readme-ov-file#how-it-works) to read and store comments made by _GitHub_ users in the `Discussions` associated with a repository.
Embed the _Giscus_ client-side script bundle on your site, configure it with the correct repository URL, and users can view and write comments (when logged into _GitHub_).
The approach is serverless, as the comments are stored on _GitHub_ and dynamically loaded from there on client side, hence perfect for a static blog, like _AstroPaper_.
## Setting up _Giscus_
_Giscus_ can be set up easily on [giscus.app](https://giscus.app/), but I will outline the process shortly still.
### Prequisites
Prequisites to get _Giscus_ working are
- the repository is [public](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/managing-repository-settings/setting-repository-visibility#making-a-repository-public)
- the [Giscus app](https://github.com/apps/giscus) is installed
- the [Discussions](https://docs.github.com/en/github/administering-a-repository/managing-repository-settings/enabling-or-disabling-github-discussions-for-a-repository) feature is turned on for your repository
If any of these conditions cannot be fulfilled for any reason, unfortunately, _Giscus_ cannot be integrated.
### Configuring _Giscus_
Next, configuring _Giscus_ is necessary. In most cases, the preselected defaults are suitable, and you should only modify them if you have a specific reason and know what you are doing. Don't worry too much about making the wrong choices; you can always adjust the configuration later on.
However you need to
- select the right language for the UI
- specify the _GitHub_ repository you want to connect, typically the repository containing your statically hosted _AstroPaper_ blog on _GitHub Pages_
- create and set an `Announcement` type discussion on _GitHub_ if you want to ensure nobody can create random comments directly on _GitHub_
- define the color scheme
After configuring the settings, _Giscus_ provides you with a generated `<script>` tag, which you will need in the next steps.
## Simple script tag
You should now have a script tag that looks like this:
```html
<script
src="https://giscus.app/client.js"
data-repo="[ENTER REPO HERE]"
data-repo-id="[ENTER REPO ID HERE]"
data-category="[ENTER CATEGORY NAME HERE]"
data-category-id="[ENTER CATEGORY ID HERE]"
data-mapping="pathname"
data-strict="0"
data-reactions-enabled="1"
data-emit-metadata="0"
data-input-position="bottom"
data-theme="preferred_color_scheme"
data-lang="en"
crossorigin="anonymous"
async
></script>
```
Simply add that to the source code of the site. Most likely, if you're using _AstroPaper_ and want to enable comments on posts, navigate to `src/layouts/PostDetails.astro` and paste it into the desired location where you want the comments to appear, perhaps underneath the `Share this post on:` buttons.
```diff
<ShareLinks />
</div>
+ <script src="https://giscus.app/client.js"
+ data-repo="[ENTER REPO HERE]"
+ data-repo-id="[ENTER REPO ID HERE]"
+ data-category="[ENTER CATEGORY NAME HERE]"
+ data-category-id="[ENTER CATEGORY ID HERE]"
+ ...
+ </script>
</main>
<Footer />
</Layout>
```
And it's done! You have successfully integrated comments in _AstroPaper_!
## React component with light/dark theme
The embedded script tag in the layout is quite static, with the _Giscus_ configuration, including `theme`, hardcoded into the layout. Given that _AstroPaper_ features a light/dark theme toggle, it would be nice for the comments to seamlessly transition between light and dark themes along with the rest of the site. To achieve this, a more sophisticated approach to embedding _Giscus_ is required.
Firstly, we are going to install the [React component](https://www.npmjs.com/package/@giscus/react) for _Giscus_:
```bash
npm i @giscus/react && npx astro add react
```
Then we create a new `Comments.tsx` React component in `src/components`:
```tsx
import Giscus, { type Theme } from "@giscus/react";
import { GISCUS } from "@/constants";
import { useEffect, useState } from "react";
interface CommentsProps {
lightTheme?: Theme;
darkTheme?: Theme;
}
export default function Comments({
lightTheme = "light",
darkTheme = "dark",
}: CommentsProps) {
const [theme, setTheme] = useState(() => {
const currentTheme = localStorage.getItem("theme");
const browserTheme = window.matchMedia("(prefers-color-scheme: dark)")
.matches
? "dark"
: "light";
return currentTheme || browserTheme;
});
useEffect(() => {
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
const handleChange = ({ matches }: MediaQueryListEvent) => {
setTheme(matches ? "dark" : "light");
};
mediaQuery.addEventListener("change", handleChange);
return () => mediaQuery.removeEventListener("change", handleChange);
}, []);
useEffect(() => {
const themeButton = document.querySelector("#theme-btn");
const handleClick = () => {
setTheme(prevTheme => (prevTheme === "dark" ? "light" : "dark"));
};
themeButton?.addEventListener("click", handleClick);
return () => themeButton?.removeEventListener("click", handleClick);
}, []);
return (
<div className="mt-8">
<Giscus theme={theme === "light" ? lightTheme : darkTheme} {...GISCUS} />
</div>
);
}
```
This _React_ component not only wraps the native _Giscus_ component, but also introduces additional props, namely `lightTheme` and `darkTheme`. Leveraging two event listeners, the _Giscus_ comments will align with the site's theme, dynamically switching between dark and light themes whenever the site or browser theme is changed.
We also need to define the `GISCUS` config, for which the optimal location is in `src/constants.ts`:
```ts
import type { GiscusProps } from "@giscus/react";
...
export const GISCUS: GiscusProps = {
repo: "[ENTER REPO HERE]",
repoId: "[ENTER REPO ID HERE]",
category: "[ENTER CATEGORY NAME HERE]",
categoryId: "[ENTER CATEGORY ID HERE]",
mapping: "pathname",
reactionsEnabled: "0",
emitMetadata: "0",
inputPosition: "bottom",
lang: "en",
loading: "lazy",
};
```
Note that specifying a `theme` here will override the `lightTheme` and `darkTheme` props, resulting in a static theme setting, similar to the previous approach of embedding _Giscus_ with the `<script>` tag.
To complete the process, add the new Comments component to `src/layouts/PostDetails.astro` (replacing the `script` tag from the previous step).
```diff
+ import Comments from "@/components/Comments";
<ShareLinks />
</div>
+ <Comments client:only="react" />
<hr class="my-6 border-dashed" />
</main>
<Footer />
</Layout>
```
And that's it!

View file

@ -1,114 +0,0 @@
---
title: How to update dependencies of AstroPaper
author: Sat Naing
pubDatetime: 2023-07-20T15:33:05.569Z
slug: how-to-update-dependencies
featured: false
draft: false
ogImage: ../../assets/images/forrest-gump-quote.png
tags:
- FAQ
description: How to update project dependencies and AstroPaper template.
---
Updating the dependencies of a project can be tedious. However, neglecting to update project dependencies is not a good idea either 😬. In this post, I will share how I usually update my projects, focusing on AstroPaper as an example. Nonetheless, these steps can be applied to other js/node projects as well.
![Forrest Gump Fake Quote](@/assets/images/forrest-gump-quote.png)
## Table of contents
## Updating Package Dependencies
There are several ways to update dependencies, and I've tried various methods to find the easiest path. One way to do it is by manually updating each package using `npm install package-name@latest`. This method is the most straightforward way of updating. However, it may not be the most efficient option.
My recommended way of updating dependencies is by using the [npm-check-updates package](https://www.npmjs.com/package/npm-check-updates). There's a good [article](https://www.freecodecamp.org/news/how-to-update-npm-dependencies/) from freeCodeCamp about that, so I won't be explaining the details of what it is and how to use that package. Instead, I'll show you my typical approach.
First, install `npm-check-updates` package globally.
```bash
npm install -g npm-check-updates
```
Before making any updates, its a good idea to check all new dependencies that can be updated.
```bash
ncu
```
Most of the time, patch dependencies can be updated without affecting the project at all. So, I usually update patch dependencies by running either `ncu -i --target patch` or `ncu -u --target patch`. The difference is that `ncu -u --target patch` will update all the patches, while `ncu -i --target patch` will give an option to toggle which package to update. Its up to you to decide which approach to take.
The next part involves updating minor dependencies. Minor package updates usually won't break the project, but it is always good to check the release notes of the respective packages. These minor updates often include some cool features that can be applied to our projects.
```bash
ncu -i --target minor
```
Last but not least, there might be some major package updates in the dependencies. So, check the rest of the dependency updates by running
```bash
ncu -i
```
If there are any major updates (or some updates you still have to make), the above command will output those remaining packages. If the package is a major version update, you have to be very careful since this will likely break the whole project. Therefore, please read the respective release note (or) docs very carefully and make changes accordingly.
If you run `ncu -i` and found no more packages to be updated, _**Congrats!!!**_ you have successfully updated all the dependencies in your project.
## Updating AstroPaper template
Like other open-source projects, AstroPaper is evolving with bug fixes, feature updates, and so on. So if youre someone who is using AstroPaper as a template, you might also want to update the template when theres a new release.
The thing is, you might already have updated the template according to your flavor. Therefore, I cant exactly show **"the one-size-fits-all perfect way"** to update the template to the most recent release. However, here are some tips to update the template without breaking your repo. Keep in mind that, most of the time, updating the package dependencies might be sufficient for you.
### Files and Directories to keep in mind
In most cases, the files and directories you might not want to override (as you've likely updated those files) are `src/content/blog/`, `src/config.ts`, `src/pages/about.md`, and other assets & styles like `public/` and `src/styles/base.css`.
If youre someone who only updates the bare minimum of the template, it should be okay to replace everything with the latest AstroPaper except the above files and directories. Its like pure Android OS and other vendor-specific OSes like OneUI. The less you modify the base, the less you have to update.
You can manually replace every file one by one, or you can use the magic of git to update everything. I wont show you the manual replacement process since it is very straightforward. If youre not interested in that straightfoward and inefficient method, bear with me 🐻.
### Updating AstroPaper using Git
**IMPORTANT!!!**
> Only do the following if you know how to resolve merge conflicts. Otherwise, youd better replace files manually or update dependencies only.
First, add astro-paper as the remote in your project.
```bash
git remote add astro-paper https://github.com/satnaing/astro-paper.git
```
Checkout to a new branch in order to update the template. If you know what youre doing and youre confident with your git skill, you can omit this step.
```bash
git checkout -b build/update-astro-paper
```
Then, pull the changes from astro-paper by running
```bash
git pull astro-paper main
```
If you face `fatal: refusing to merge unrelated histories` error, you can resolve that by running the following command
```bash
git pull astro-paper main --allow-unrelated-histories
```
After running the above command, youre likely to encounter conflicts in your project. You'll need to resolve these conflicts manually and make the necessary adjustments according to your needs.
After resolving the conflicts, test your blog thoroughly to ensure everything is working as expected. Check your articles, components, and any customizations you made.
Once you're satisfied with the result, it's time to merge the update branch into your main branch (only if you are updating the template in another branch). Congratulations! You've successfully updated your template to the latest version. Your blog is now up-to-date and ready to shine! 🎉
## Conclusion
In this article, I've shared some of my insights and processes for updating dependencies and the AstroPaper template. I genuinely hope this article proves valuable and assists you in managing your projects more efficiently.
If you have any alternative or improved approaches for updating dependencies/AstroPaper, I would love to hear from you. Thus, don't hesitate to start a discussion in the repository, email me, or open an issue. Your input and ideas are highly appreciated!
Please understand that my schedule is quite busy these days, and I may not be able to respond quickly. However, I promise to get back to you as soon as possible. 😬
Thank you for taking the time to read this article, and I wish you all the best with your projects!

View file

@ -1,171 +0,0 @@
---
author: Sat Naing
pubDatetime: 2022-09-26T12:13:24Z
modDatetime: 2024-01-04T09:09:06Z
title: Predefined color schemes
slug: predefined-color-schemes
featured: false
draft: false
tags:
- color-schemes
description:
Some of the well-crafted, predefined color schemes for AstroPaper blog
theme.
---
I've crafted some predefined color schemes for this AstroPaper blog theme. You can replace these color schemes with the original ones.
If you don't know how you can configure color schemes, check [this blog post](https://astro-paper.pages.dev/posts/customizing-astropaper-theme-color-schemes/).
## Table of contents
## Light color schemes
Light color scheme has to be defined using the css selector `:root` and `html[data-theme="light"]`.
### Lobster
![lobster-color-scheme](https://user-images.githubusercontent.com/53733092/192282447-1d222faf-a3ce-44a9-9cfe-ac873155e5a9.png)
```css
:root,
html[data-theme="light"] {
--background: #f6eee1;
--foreground: #012c56;
--accent: #e14a39;
--muted: #efd8b0;
--border: #dc9891;
}
```
### Leaf Blue
![leaf-blue-color-scheme](https://user-images.githubusercontent.com/53733092/192318782-e80e3c39-54b5-423e-8f4b-9ae60402fc8d.png)
```css
:root,
html[data-theme="light"] {
--background: #f2f5ec;
--foreground: #353538;
--accent: #1158d1;
--muted: #bbc789;
--border: #7cadff;
}
```
### Pinky light
![pinky-color-scheme](https://user-images.githubusercontent.com/53733092/192286510-892d0042-2d6d-471e-bb72-954221ae2d17.png)
```css
:root,
html[data-theme="light"] {
--background: #fafcfc;
--foreground: #222e36;
--accent: #d3006a;
--muted: #f1bad4;
--border: #e3a9c6;
}
```
## Dark color schemes
Dark color scheme has to be defined as `html[data-theme="dark"]`.
### AstroPaper 1 original Dark Theme
![AstroPaper 1 default dark theme](https://user-images.githubusercontent.com/53733092/215769153-13b0ad8d-5ba2-44b1-af06-e5ae61293f62.png)
```css
html[data-theme="dark"] {
--background: #2f3741;
--foreground: #e6e6e6;
--accent: #1ad9d9;
--muted: #596b81;
--border: #3b4655;
}
```
### Deep Oyster
![deep-oyster-color-scheme](https://user-images.githubusercontent.com/53733092/192314524-45ec5904-3d8f-450a-9edf-1e32c5e11d6c.png)
```css
html[data-theme="dark"] {
--background: #21233d;
--foreground: #f4f7f5;
--accent: #ff5256;
--muted: #4a4e86;
--border: #b12f32;
}
```
### Pikky dark
![pinky-dark-color-scheme](https://user-images.githubusercontent.com/53733092/192307050-fbd55326-911c-4001-87c6-a8ad9378ac2e.png)
```css
html[data-theme="dark"] {
--background: #353640;
--foreground: #e9edf1;
--accent: #ff78c8;
--muted: #715566;
--border: #86436b;
}
```
### Astro dark (High Contrast)
![astro-dark-color-scheme](https://user-images.githubusercontent.com/53733092/215680520-59427bb0-f4cb-48c0-bccc-f182a428d72d.svg)
```css
html[data-theme="dark"] {
--background: #212737;
--foreground: #eaedf3;
--accent: #ff6b01;
--muted: #8a3302;
--border: #ab4b08;
}
```
### Astro dark (New default dark theme in AstroPaper 2)
![new dark color scheme - low contrast](https://user-images.githubusercontent.com/53733092/215772856-d5b7ae35-ddaa-4ed6-b0bf-3fa5dbcf834c.png)
```css
html[data-theme="dark"] {
--background: #212737; /* lower contrast background */
--foreground: #eaedf3;
--accent: #ff6b01;
--muted: #8a3302;
--border: #ab4b08;
}
```
### Astro Deep Purple (New dark theme in AstroPaper 3)
![AstroPaper v3 new theme](https://github.com/satnaing/astro-paper/assets/53733092/c8b5d7e1-a3bc-4852-a5ad-4abf7b3cec79)
```css
html[data-theme="dark"] {
--background: #212737;
--foreground: #eaedf3;
--accent: #eb3fd3;
--muted: #7d4f7c;
--border: #642451;
}
```
### AstroPaper v4 Special (New dark theme in AstroPaper 4)
![AstroPaper v4 new theme](https://github.com/satnaing/astro-paper/assets/53733092/66eb74dc-7a0e-4f2e-982d-25f5c443b25a)
```css
html[data-theme="dark"] {
--background: #000123;
--accent: #617bff;
--foreground: #eaedf3;
--muted: #0c0e4f;
--border: #303f8a;
}
```

View file

@ -1,191 +0,0 @@
---
author: Simon Smale
pubDatetime: 2024-01-03T20:40:08Z
modDatetime: 2024-01-08T18:59:05Z
title: How to use Git Hooks to set Created and Modified Dates
featured: false
draft: false
tags:
- docs
- FAQ
canonicalURL: https://smale.codes/posts/setting-dates-via-git-hooks/
description: How to use Git Hooks to set your Created and Modified Dates on AstroPaper
---
In this post I will explain how to use the pre-commit Git hook to automate the input of the created (`pubDatetime`) and modified (`modDatetime`) in the AstroPaper blog theme frontmatter
## Table of contents
## Have them Everywhere
[Git hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) are great for automating tasks like [adding](https://gist.github.com/SSmale/3b380e5bbed3233159fb7031451726ea) or [checking](https://itnext.io/using-git-hooks-to-enforce-branch-naming-policy-ffd81fa01e5e) the branch name to your commit messages or [stopping you committing plain text secrets](https://gist.github.com/SSmale/367deee757a9b2e119d241e120249000). Their biggest flaw is that client-side hooks are per machine.
You can get around this by having a `hooks` directory and manually copy them to the `.git/hooks` directory or set up a symlink, but this all requires you to remember to set it up, and that is not something I am good at doing.
As this project uses npm, we are able to make use of a package called [Husky](https://typicode.github.io/husky/) (this is already installed in AstroPaper) to automatically install the hooks for us.
> Update! In AstroPaper [v4.3.0](https://github.com/satnaing/astro-paper/releases/tag/v4.3.0), the pre-commit hook has been removed in favor of GitHub Actions. However, you can easily [install Husky](https://typicode.github.io/husky/get-started.html) yourself.
## The Hook
As we want this hook to run as we commit the code to update the dates and then have that as part of our change we are going to use the `pre-commit` hook. This has already been set up by this AstroPaper project, but if it hadn't, you would run `npx husky add .husky/pre-commit 'echo "This is our new pre-commit hook"'`.
Navigating to the `hooks/pre-commit` file, we are going to add one or both of the following snippets.
### Updating the modified date when a file is edited
---
UPDATE:
This section has been updated with a new version of the hook that is smarter. It will now not increment the `modDatetime` until the post is published. On the first publish, set the draft status to `first` and watch the magic happen.
---
```shell
# Modified files, update the modDatetime
git diff --cached --name-status |
grep -i '^M.*\.md$' |
while read _ file; do
filecontent=$(cat "$file")
frontmatter=$(echo "$filecontent" | awk -v RS='---' 'NR==2{print}')
draft=$(echo "$frontmatter" | awk '/^draft: /{print $2}')
if [ "$draft" = "false" ]; then
echo "$file modDateTime updated"
cat $file | sed "/---.*/,/---.*/s/^modDatetime:.*$/modDatetime: $(date -u "+%Y-%m-%dT%H:%M:%SZ")/" > tmp
mv tmp $file
git add $file
fi
if [ "$draft" = "first" ]; then
echo "First release of $file, draft set to false and modDateTime removed"
cat $file | sed "/---.*/,/---.*/s/^modDatetime:.*$/modDatetime:/" | sed "/---.*/,/---.*/s/^draft:.*$/draft: false/" > tmp
mv tmp $file
git add $file
fi
done
```
`git diff --cached --name-status` gets the files from git that have been staged for committing. The output looks like:
```shell
A src/content/blog/setting-dates-via-git-hooks.md
```
The letter at the start denotes what action has been taken, in the above example the file has been added. Modified files have `M`
We pipe that output into the grep command where we are looking at each line to find that have been modified. The line needs to start with `M` (`^(M)`), have any number of characters after that (`.*`) and end with the `.md` file extension (`.(md)$`).This is going to filter out the lines that are not modified markdown files `egrep -i "^(M).*\.(md)$"`.
---
#### Improvement - More Explicit
This could be added to only look for files that we markdown files in the `blog` directory, as these are the only ones that will have the right frontmatter
---
The regex will capture the two parts, the letter and the file path. We are going to pipe this list into a while loop to iterate over the matching lines and assign the letter to `a` and the path to `b`. We are going to ignore `a` for now.
To know the draft staus of the file, we need its frontmatter. In the following code we are using `cat` to get the content of the file, then using `awk` to split the file on the frontmatter separator (`---`) and taking the second block (the fonmtmatter, the bit between the `---`). From here we are using `awk` again to find the draft key and print is value.
```shell
filecontent=$(cat "$file")
frontmatter=$(echo "$filecontent" | awk -v RS='---' 'NR==2{print}')
draft=$(echo "$frontmatter" | awk '/^draft: /{print $2}')
```
Now we have the value for `draft` we are going to do 1 of 3 things, set the modDatetime to now (when draft is false `if [ "$draft" = "false" ]; then`), clear the modDatetime and set draft to false (when draft is set to first `if [ "$draft" = "first" ]; then`), or nothing (in any other case).
The next part with the sed command is a bit magical to me as I don't often use it, it was copied from [another blog post on doing something similar](https://mademistakes.com/notes/adding-last-modified-timestamps-with-git/). In essence, it is looking inside the frontmatter tags (`---`) of the file to find the `pubDatetime:` key, getting the full line and replacing it with the `pubDatetime: $(date -u "+%Y-%m-%dT%H:%M:%SZ")/"` same key again and the current datetime formatted correctly.
This replacement is in the context of the whole file so we put that into a temporary file (`> tmp`), then we move (`mv`) the new file into the location of the old file, overwriting it. This is then added to git ready to be committed as if we made the change ourselves.
---
#### NOTE
For the `sed` to work the frontmatter needs to already have the `modDatetime` key in the frontmatter. There are some other changes you will need to make for the app to build with a blank date, see [further down](#empty-moddatetime-changes)
---
### Adding the Date for new files
Adding the date for a new file is the same process as above, but this time we are looking for lines that have been added (`A`) and we are going to replace the `pubDatetime` value.
```shell
# New files, add/update the pubDatetime
git diff --cached --name-status | egrep -i "^(A).*\.(md)$" | while read a b; do
cat $b | sed "/---.*/,/---.*/s/^pubDatetime:.*$/pubDatetime: $(date -u "+%Y-%m-%dT%H:%M:%SZ")/" > tmp
mv tmp $b
git add $b
done
```
---
#### Improvement - Only Loop Once
We could use the `a` variable to switch inside the loop and either update the `modDatetime` or add the `pubDatetime` in one loop.
---
## Populating the frontmatter
If your IDE supports snippets then there is the option to create a custom snippet to populate the frontmatter.[In AstroPaper v4 will come with one for VSCode by default.](https://github.com/satnaing/astro-paper/pull/206)
<video autoplay muted="muted" controls plays-inline="true" class="border border-skin-line">
<source src="https://github.com/satnaing/astro-paper/assets/17761689/e13babbc-2d78-405d-8758-ca31915e41b0" type="video/mp4">
</video>
## Empty `modDatetime` changes
To allow Astro to compile the markdown and do its thing, it needs to know what is expected in the frontmatter. It does this via the config in `src/content/config.ts`
To allow the key to be there with no value we need to edit line 10 to add the `.nullable()` function.
```typescript
const blog = defineCollection({
type: "content",
schema: ({ image }) =>
z.object({
author: z.string().default(SITE.author),
pubDatetime: z.date(),
- modDatetime: z.date().optional(),
+ modDatetime: z.date().optional().nullable(),
title: z.string(),
featured: z.boolean().optional(),
draft: z.boolean().optional(),
tags: z.array(z.string()).default(["others"]),
ogImage: image().or(z.string()).optional(),
description: z.string(),
canonicalURL: z.string().optional(),
readingTime: z.string().optional(),
}),
});
```
To stop the IDE complaining in the blog engine files I have also done the following:
1. added `| null` to line 15 in `src/layouts/Layout.astro` so that it looks like
```typescript
export interface Props {
title?: string;
author?: string;
description?: string;
ogImage?: string;
canonicalURL?: string;
pubDatetime?: Date;
modDatetime?: Date | null;
}
```
<!-- This needs to be 2 as it doesn't pick it up with the code block -->
2. added `| null` to line 5 in `src/components/Datetime.tsx` so that it looks like
```typescript
interface DatetimesProps {
pubDatetime: string | Date;
modDatetime: string | Date | undefined | null;
}
```

View file

@ -16,12 +16,12 @@ import { SITE } from "@/config";
<div class="mb-14 flex flex-col items-center justify-center">
<h1 class="text-9xl font-bold text-accent">404</h1>
<span aria-hidden="true">¯\_(ツ)_/¯</span>
<p class="mt-4 text-2xl sm:text-3xl">Page Not Found</p>
<p class="mt-4 text-2xl sm:text-3xl">Page inexistante (supprimée (non trouvée (absente ( ton temps (non-existante)))))</p>
<LinkButton
href="/"
class="my-6 text-lg underline decoration-dashed underline-offset-8"
>
Go back home
Retournez d'où vous venez (accueil)
</LinkButton>
</div>
</main>

View file

@ -1,36 +0,0 @@
---
layout: ../layouts/AboutLayout.astro
title: "About"
---
AstroPaper is a minimal, responsive and SEO-friendly Astro blog theme. I designed and crafted this based on [my personal blog](https://satnaing.dev/blog).
This theme is aimed to be accessible out of the box. Light and dark mode are supported by
default and additional color schemes can also be configured.
This theme is self-documented \_ which means articles/posts in this theme can also be considered as documentations. So, see the documentation for more info.
<div>
<img src="/dev.svg" class="sm:w-1/2 mx-auto" alt="coding dev illustration">
</div>
## Tech Stack
This theme is written in vanilla JavaScript (+ TypeScript for type checking) and a little bit of ReactJS for some interactions. TailwindCSS is used for styling; and Markdown is used for blog contents.
## Features
Here are certain features of this site.
- fully responsive and accessible
- SEO-friendly
- light & dark mode
- fuzzy search
- super fast performance
- draft posts
- pagination
- sitemap & rss feed
- highly customizable
If you like this theme, you can star/contribute to the [repo](https://github.com/satnaing/astro-paper).
Or you can even give any feedback via my [email](mailto:contact@satnaing.dev).

6
src/pages/apropos.md Normal file
View file

@ -0,0 +1,6 @@
---
layout: ../layouts/AboutLayout.astro
title: "À propos"
---
Je sais pas trop quoi vous dire de plus honnêtement. Merci d'être là, c'est déjà pas mal !

View file

@ -16,24 +16,24 @@ if (!SITE.showArchives) {
const posts = await getCollection("blog", ({ data }) => !data.draft);
const months = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
"Janvier",
"Févirer",
"Mars",
"Avril",
"Mai",
"Juin",
"Juillet",
"At",
"Septembre",
"Octobre",
"Novembre",
"Decembre",
];
---
<Layout title={`Archives | ${SITE.title}`}>
<Header />
<Main pageTitle="Archives" pageDesc="All the articles I've archived.">
<Main pageTitle="Archives" pageDesc="Tous les posts archivés">
{
Object.entries(
getPostsByGroupCondition(posts, post =>

View file

@ -25,7 +25,7 @@ const recentPosts = sortedPosts.filter(({ data }) => !data.featured);
<main id="main-content" data-layout="index">
<section id="hero" class="pt-8 pb-6">
<h1 class="my-4 inline-block text-4xl font-bold sm:my-8 sm:text-5xl">
Mingalaba
Avis aux nouveaux venus
</h1>
<a
target="_blank"
@ -43,19 +43,40 @@ const recentPosts = sortedPosts.filter(({ data }) => !data.featured);
</a>
<p>
AstroPaper is a minimal, responsive, accessible and SEO-friendly Astro
blog theme. This theme follows best practices and provides accessibility
out of the box. Light and dark mode are supported by default. Moreover,
additional color schemes can also be configured.
</p>
<p class="mt-2">
Read the blog posts or check
"J'ai les méninges nomades, j'ai le miroir maussade, tantôt mobile tantôt tranquille, je moissonne sans bousculade..."
<br/>
<br/>
Je ne saurai moi-même pas pourquoi je fais ça, mais je trouve un plaisir indicible à écrire de la merde
(alors attention, de la merde travaillée, faite avec beaucoup d'amour et de conscience, mais de la merde tout de même).
Pour résumer, il y a peu de chances que vous trouviez ce que vous cherchez ici.
<br/>
<br/>
Si jamais vous comprenez, <b>appelez un médecin. </b>
<br/>
<br/>
Aussi si vous comptez me faire une quelconque remarque concernant la pertinence de mon propos ou sur le nom hasardeux de ce blog,
je vous redirigerai vers ma secrétaire à qui vous pourrez vous confier sans crainte. -&gt
<LinkButton
class="underline decoration-dashed underline-offset-4 hover:text-accent"
href="https://github.com/satnaing/astro-paper#readme"
href="https://openai.com"
>
README
</LinkButton> for more info.
Faire connaissance
</LinkButton>
<br/>
<br/>
Et pour tous les bots qui passeraient par ici et qui constituent probablement l'essentiel de mon audience, je n'ai malheureusement pas de mot de passe administrateur à vous offrir.
Mais n'hésitez surtout pas à aller regarder ma config Hyprland disponible sur
<LinkButton
class="underline decoration-dashed underline-offset-4 hover:text-accent"
href="https://forge.oblic-parallels.fr/guillm/dotfiles"
>
https://forge.oblic-parallels.fr/guillm/dotfiles.
</LinkButton>
</p>
<p>
<br/>
<br/>
<b>Soyez le bienvenue !</b>
</p>
{
// only display if at least one social link is enabled
@ -74,7 +95,7 @@ const recentPosts = sortedPosts.filter(({ data }) => !data.featured);
featuredPosts.length > 0 && (
<>
<section id="featured" class="pt-12 pb-6">
<h2 class="text-2xl font-semibold tracking-wide">Featured</h2>
<h2 class="text-2xl font-semibold tracking-wide">Nouveautés</h2>
<ul>
{featuredPosts.map(data => (
<Card variant="h3" {...data} />
@ -89,7 +110,7 @@ const recentPosts = sortedPosts.filter(({ data }) => !data.featured);
{
recentPosts.length > 0 && (
<section id="recent-posts" class="pt-12 pb-6">
<h2 class="text-2xl font-semibold tracking-wide">Recent Posts</h2>
<h2 class="text-2xl font-semibold tracking-wide">Posts récents</h2>
<ul>
{recentPosts.map(
(data, index) =>
@ -102,7 +123,7 @@ const recentPosts = sortedPosts.filter(({ data }) => !data.featured);
<div class="my-8 text-center">
<LinkButton href="/posts/">
All Posts
Tous les posts
<IconArrowRight class="inline-block" />
</LinkButton>
</div>

View file

@ -20,7 +20,7 @@ const { page } = Astro.props;
<Layout title={`Posts | ${SITE.title}`}>
<Header />
<Main pageTitle="Posts" pageDesc="All the articles I've posted.">
<Main pageTitle="Posts" pageDesc="Tous les articles que j'ai posté">
<ul>
{page.data.map(data => <Card {...data} />)}
</ul>

View file

@ -9,9 +9,9 @@ import { SITE } from "@/config";
const backUrl = SITE.showBackButton ? `${Astro.url.pathname}` : "/";
---
<Layout title={`Search | ${SITE.title}`}>
<Layout title={`Rechercher | ${SITE.title}`}>
<Header />
<Main pageTitle="Search" pageDesc="Search any article ...">
<Main pageTitle="Rechercher" pageDesc="Powered by Goouillem">
<div id="pagefind-search" transition:persist data-backurl={backUrl}></div>
</Main>
<Footer />

View file

@ -36,7 +36,7 @@ const { page, tagName } = Astro.props;
<Main
pageTitle={[`Tag:`, `${tagName}`]}
titleTransition={tag}
pageDesc={`All the articles with the tag "${tagName}".`}
pageDesc={`Tous les articles avec le tag "${tagName}".`}
>
<h1 slot="title" transition:name={tag}>{`Tag:${tag}`}</h1>
<ul>

View file

@ -15,7 +15,7 @@ let tags = getUniqueTags(posts);
<Layout title={`Tags | ${SITE.title}`}>
<Header />
<Main pageTitle="Tags" pageDesc="All the tags used in posts.">
<Main pageTitle="Tags" pageDesc="Tous les tags">
<ul>
{tags.map(({ tag, tagName }) => <Tag {tag} {tagName} size="lg" />)}
</ul>