This is my personal website and blog built with Astro, a modern static site generator that delivers lightning-fast performance by shipping minimal JavaScript.
The site follows a standard Astro structure:
src/pages- All content pages and blog postssrc/layouts- The main Layout component used across the sitesrc/components- Reusable UI components
The theme uses a customized dark/light mode toggle with Tailwind for styling and includes responsive design throughout.
# Install dependencies
npm install
# Start the development server
npm run dev
# Build for production
npm run build
# Preview the production build
npm run previewTo create a new blog post:
-
Create a new Markdown file in the
src/pages/posts/directory following this naming convention:YYYY-MM-DD-post-title-slug.md -
Add the required frontmatter at the top of your file:
--- title: Your Post Title date: YYYY-MM-DD description: A brief description of your post --- # Your Post Title Post content goes here...
-
Write your content using standard Markdown syntax.
-
Posts are automatically routed to
/YYYY/MM/DD/post-title-slugand will appear on the homepage and blog index page when built.
Blog images are hosted on Cloudinary for automatic optimization and CDN delivery.
Use Cloudinary URLs directly in your markdown/MDX:
<img src="https://res.cloudinary.com/bdougie/image/upload/f_auto,q_auto/blog/your-image-name" alt="Description" width="600" />The f_auto,q_auto parameters automatically serve the best format (WebP, AVIF) and quality for each browser.
- Add images to
public/images/ - Run the upload script during build (or manually):
npm run upload:images
- Images are uploaded to Cloudinary's
blog/folder - Use the Cloudinary URL in your post
Social cards are pre-generated static images stored on Cloudinary. This ensures fast, reliable previews when sharing posts on LinkedIn, Bluesky, Twitter, etc.
- Each blog post has a static OG image at:
https://res.cloudinary.com/bdougie/image/upload/og/{slug}.png - Images are 1200x630px with the post title on a black background
- Non-blog pages use a default OG image
For a new post:
npm run og:generate -- your-post-slugOptions:
npm run og:generate -- your-post-slug --local # Save locally only, don't upload
npm run og:generate -- your-post-slug --dry-run # Preview without savingFor bulk migration (all posts):
npm run og:migrateOG image generation requires Cloudinary credentials in .env:
CLOUDINARY_CLOUD_NAME=bdougie
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
Blog posts can display likes, reposts, and replies from a linked Bluesky post.
- Publish your blog post
- Create a Bluesky post linking to your article
- Add the
blueskyUrlto your post's frontmatter:
---
title: Your Post Title
date: 2026-01-18
description: Post description
blueskyUrl: "https://bsky.app/profile/your-handle/post/abc123"
---- Displays like count with stacked avatars of people who liked
- Shows reply count and recent replies
- Repost count
- Links back to the Bluesky post for engagement
- Compact mode on homepage, full mode on post pages
For more stable URLs (handles can change), use the DID format:
blueskyUrl: "https://bsky.app/profile/did:plc:abc123/post/xyz789"You can find your DID by inspecting any of your Bluesky post URLs in the API.
The site uses Tailwind CSS with a custom color scheme:
- Primary: Dark theme background
- Secondary: Dark accents
- Accent/Highlight: Gold accents for buttons and links
The typography is enhanced with the @tailwindcss/typography plugin for rich text styling in blog posts.
This repository uses CodeBunny for automated AI-powered code reviews on pull requests.
The workflow requires the following repository secrets and variables:
Secrets:
CONTINUE_API_KEY- Your Continue API keyAPP_PRIVATE_KEY- (Optional) GitHub App private key for enhanced authentication
Variables:
CONTINUE_ORG- Your Continue Hub organization nameCONTINUE_CONFIG- Your Continue assistant slug (format:owner/package-name)APP_ID- (Optional) GitHub App ID for enhanced authentication
CodeBunny automatically reviews PRs when they are opened, synchronized, or marked ready for review. You can also trigger a review by commenting @codebunny on any PR.
This site is deployed on Netlify, which automatically builds and deploys the site when changes are pushed to the main branch.
| 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 astro ... |
Run CLI commands like astro add, astro check |
npm run og:generate |
Generate OG image for a single post |
npm run og:migrate |
Generate OG images for all posts (one-time) |
npm run og:check |
Verify all OG images exist on Cloudinary |
npm run upload:images |
Upload local images to Cloudinary |