Personal website and blog built with Astro, Preact, and TypeScript.
- Framework: Astro - Static site generator
- UI Library: Preact - Lightweight React alternative
- Language: TypeScript
- Content: Markdown with frontmatter
- Backend: Netlify Functions - Serverless functions for contact form
- Deployment: Netlify
/
├── src/
│ ├── components/ # Preact components
│ │ ├── Header.tsx
│ │ ├── Footer.tsx
│ │ ├── Hero.tsx
│ │ ├── BlogPostCard.tsx
│ │ ├── Pagination.tsx
│ │ └── ContactForm.tsx
│ ├── content/ # Content collections
│ │ ├── config.ts # Content schema definitions
│ │ ├── posts/ # Blog posts (markdown)
│ │ └── pages/ # Static pages (markdown)
│ ├── layouts/ # Astro layouts
│ │ ├── BaseLayout.astro
│ │ ├── Homepage.astro
│ │ ├── Post.astro
│ │ ├── Page.astro
│ │ └── PageError.astro
│ ├── pages/ # File-based routing
│ │ ├── index.astro
│ │ ├── contact.astro
│ │ ├── 404.astro
│ │ └── posts/
│ │ ├── [...page].astro # Paginated posts list
│ │ └── [slug].astro # Individual blog posts
│ └── styles/ # Global styles
│ └── global.css
├── netlify/
│ └── functions/ # Netlify serverless functions
│ └── contact.ts # Contact form handler (Telegram integration)
├── public/ # Static assets
├── astro.config.mjs # Astro configuration
├── netlify.toml # Netlify deployment config
└── tsconfig.json # TypeScript configuration- Bun (or Node.js 18+)
bun installStart the development server:
bun run devThe site will be available at http://localhost:4321
Build for production:
bun run buildThe static files will be generated in the dist/ directory.
Preview the production build locally:
bun run preview- Create a new
.mdfile insrc/content/posts/ - Add frontmatter with the following fields:
---
title: Your Post Title
date: 2025-01-01
layout: Post
hero: https://example.com/image.jpg # Optional
---
Your content here...- Create a new
.mdfile insrc/content/pages/ - Add frontmatter:
---
title: Page Title
layout: Page
hero: https://example.com/image.jpg # Optional
---
Your content here...The blog posts page supports pagination with 10 posts per page. You can customize the number of posts per page by editing the pageSize parameter in src/pages/posts/[...page].astro:
return paginate(sortedPosts, { pageSize: 10 }); // Change 10 to your desired numberThe pagination component shows:
- Current page and total pages
- Previous/Next navigation
- Numbered page links with ellipsis for large page counts
- Fully accessible with ARIA labels
The contact page uses a Netlify Function to send form submissions to Telegram via the Bot API. The site is fully static with serverless backend for the contact form.
Architecture:
- Static site generated with Astro
- Contact form (Preact component) on
/contact - Netlify Function at
/.netlify/functions/contacthandles submissions - Function sends message to Telegram Bot API
Setup:
-
Get Telegram Credentials:
- Create a bot with @BotFather on Telegram
- Copy the bot token
- Message your bot, then visit
https://api.telegram.org/bot<YOUR_TOKEN>/getUpdatesto find your chat ID
-
Configure Environment Variables:
- For local development: Create
.envfile (see.env.example) - For production: Add to Netlify Dashboard → Site settings → Environment variables
TELEGRAM_BOT_TOKENTELEGRAM_CHAT_ID
- For local development: Create
Features:
- Client-side validation
- Character limits (100 for name, 2000 for message)
- Loading states and error handling
- Success/error messages
- Fully accessible form with ARIA attributes
- Serverless architecture (no server needed)
This site is configured for deployment to Netlify:
- Connect your repository to Netlify
- Build command:
bun run build - Publish directory:
dist - Environment Variables: Add your Telegram credentials to Netlify:
TELEGRAM_BOT_TOKENTELEGRAM_CHAT_ID
Netlify will automatically deploy on every push to the main branch.
All commands are run from the root of the project:
| Command | Action |
|---|---|
bun install |
Install dependencies |
bun run dev |
Start dev server at localhost:4321 |
bun run build |
Build production site to ./dist/ |
bun run preview |
Preview build locally before deploying |
bun run astro ... |
Run Astro CLI commands |
Copyright © 2025 Miguel Palau. All rights reserved.