Here you will find short developer posts all around my daily work. π
This blog is built using the AstroPaper theme, a minimal, responsive, and accessible blog theme for Astro. The theme provides:
- Static Site Generation (SSG) with Astro's island architecture
- Responsive design optimized for mobile and desktop
- SEO-friendly with proper meta tags and Open Graph support
- Accessibility features following WCAG guidelines
- Dark/Light mode toggle with system preference detection
- Fast search functionality powered by FuseJS
- RSS feed generation for blog posts
- Sitemap generation for better SEO
Main Framework - Astro - Static site generator with islands architecture
Theme - AstroPaper - Minimal, responsive blog theme
Type Checking - TypeScript - Static type checking
Component Framework - ReactJS - Interactive components (search, theme toggle)
Styling - TailwindCSS - Utility-first CSS framework
Content Management - Astro Content Collections - Type-safe content management
Markdown Processing - Remark & Rehype - Markdown to HTML processing
UI/UX - Figma - Design and prototyping
Fuzzy Search - FuseJS - Client-side search functionality
Icons - Boxicons | Tablers - Icon libraries
Code Formatting - Prettier - Code formatting
Deployment - Cloudflare Pages - Static site hosting
Illustration in About Page - https://freesvgillustration.com
Linting - ESLint - JavaScript/TypeScript linting
giscus - GitHub Discussions-powered comments system
Social Media Integration - Configurable social links and sharing
Open Graph Images - Dynamic OG image generation for posts
Analytics Ready - Easy integration with Google Analytics or other services
- Hydration Strategy: Components are hydrated only when needed using Astro's
client:*directives - Performance: Minimal JavaScript shipped to the client, better Core Web Vitals
- Framework Agnostic: Can use React, Vue, Svelte, or vanilla JavaScript components
- Type Safety: Strongly typed frontmatter validation using Zod schemas
- Content Management: Organized blog posts with automatic slug generation
- Markdown Support: Extended markdown with custom remark/rehype plugins
- Build Time: All pages are pre-rendered at build time
- SEO Optimization: Perfect SEO scores with proper meta tags and structured data
- Fast Loading: Optimized assets and minimal JavaScript for blazing fast performance
- RSS Feed: Automatically generated RSS feed for blog subscribers
- Sitemap: Dynamic sitemap generation for search engines
- Open Graph: Custom OG image generation for social media sharing
/
βββ public/ # Static assets
β βββ assets/ # Images, icons, and media files
β βββ favicon.svg # Site favicon
β βββ toggle-theme.js # Theme toggle functionality
βββ src/
β βββ components/ # Reusable Astro and React components
β β βββ Card.tsx # Blog post cards (React)
β β βββ Search.tsx # Search functionality (React)
β β βββ *.astro # Astro components (Header, Footer, etc.)
β βββ content/ # Content collections
β β βββ blog/ # Blog posts (Markdown/MDX)
β β βββ docs/ # Documentation pages
β β βββ config.ts # Content collection schemas
β βββ layouts/ # Page layouts
β β βββ Layout.astro # Base layout with head, SEO
β β βββ PostDetails.astro # Blog post layout
β β βββ Posts.astro # Blog listing layout
β βββ pages/ # File-based routing
β β βββ index.astro # Homepage
β β βββ about.md # About page
β β βββ posts/ # Blog post pages
β β βββ tags/ # Tag-based filtering
β β βββ og.png.ts # Dynamic OG image generation
β βββ styles/ # Global styles
β β βββ base.css # Base styles and Tailwind imports
β βββ utils/ # Utility functions
β βββ getSortedPosts.ts # Blog post sorting
β βββ getUniqueTags.ts # Tag extraction
β βββ og-templates/ # OG image templates
βββ astro.config.ts # Astro configuration
βββ tailwind.config.cjs # Tailwind CSS configuration
βββ tsconfig.json # TypeScript configuration
The easiest way to run this project locally is to run the following command in your desired directory.
# npm 6.x
npm create astro@latest --template satnaing/astro-paper
# npm 7+, extra double-dash is needed:
npm create astro@latest -- --template satnaing/astro-paper
# yarn
yarn create astro --template satnaing/astro-paperYou can easily add your Google Site Verification HTML tag in AstroPaper using environment variable. This step is optional. If you don't add the following env variable, the google-site-verification tag won't appear in the html <head> section.
# in your environment variable file (.env)
PUBLIC_GOOGLE_SITE_VERIFICATION=your-google-site-verification-valueThis project uses Microsoft Clarity for privacy-friendly, in-depth analytics and user behavior insights.
Microsoft Clarity is a free analytics tool that provides:
- Session recordings: See how real users interact with your site
- Heatmaps: Visualize where users click, scroll, and spend time
- User journey analysis: Understand navigation paths and drop-off points
- Performance metrics: Identify slow pages and usability issues
- Privacy-first: No sampling, GDPR-compliant, and does not track personal data
- Improve UX: Discover friction points and optimize user experience
- Content insights: See which blog posts and features attract the most attention
- Debugging: Replay sessions to reproduce and fix bugs
- No cost: 100% free, no traffic limits
- The official Clarity tracking script is injected globally in the main layout (
src/layouts/Layout.astro). - Each page view is tracked, and a unique user/session ID is used (from localStorage or fallback to 'anonymous').
- The current page path is sent as a custom page ID, so you can analyze single blog post views in Clarity's dashboard.
- No personal data is collected; all analytics are anonymous and privacy-friendly.
Integration snippet:
<script type="text/javascript">
(function (c, l, a, r, i, t, y) {
c[a] =
c[a] ||
function () {
(c[a].q = c[a].q || []).push(arguments);
};
t = l.createElement(r);
t.async = 1;
t.src = "https://www.clarity.ms/tag/" + i;
y = l.getElementsByTagName(r)[0];
y.parentNode.insertBefore(t, y);
})(window, document, "clarity", "script", "<your projectID here>");
</script>
<script>
const clarityUserId = window.localStorage.getItem("userId") || "anonymous";
const clarityPageId = window.location.pathname;
if (window.clarity && typeof window.clarity.identify === "function") {
window.clarity.identify(clarityUserId, undefined, clarityPageId);
}
</script>For more, see clarity.microsoft.com.
All commands are run from the root of the project, from a terminal:
Note! For
Dockercommands we must have it installed in your machine.
| Command | Action |
|---|---|
npm install |
Installs dependencies |
npm run dev |
Starts local dev server at localhost:4321 |
npm run build |
Build your production site to ./dist/ |
npm run preview |
Preview your build locally, before deploying |
npm run format:check |
Check code format with Prettier |
npm run format |
Format codes with Prettier |
npm run sync |
Generates TypeScript types for all Astro modules. Learn more. |
npm run cz |
Commit code changes with commitizen |
npm run lint |
Lint with ESLint |
docker compose up -d |
Run AstroPaper on docker, You can access with the same hostname and port informed on dev command. |
docker compose run app npm install |
You can run any command above into the docker container. |
Warning! Windows PowerShell users may need to install the concurrently package if they want to run diagnostics during development (
astro check --watch & astro dev). For more info, see this issue.
Licensed under the MIT License, Copyright Β© 2025