In two days, I built a small-to-medium Blog + micro-interactive site with Astro, from design to launch. Along the way I hit countless “pitfalls,” but also gained some insights worth sharing.
1. Be the Owner of Your Project — Plan the Overall Architecture First
The overall design of this project:
A content site focused on psychology, technology, and humanities, with several modules:
- Introduction: site introduction, author introduction
- Psychology: curated articles from third-party platforms, personal blog, psychology mini-app or quiz
- Tech Frontier: curated articles from third-party platforms, personal blog, AI mini-app or quiz
- Humanities: curated articles from third-party platforms, personal blog
In the AI era, it’s hard to have AI do the complete requirement design for you. Only when you’ve thought it through will development efficiency improve.
Tip: Clarify requirements with an AI agent. This step is a must-to-be-done and will greatly boost development efficiency.
Once the use case is clear, IT architecture implementation becomes easier. Start with these questions:
- What is the core purpose of this site? Personal branding, content accumulation, or building a reader base? This affects the homepage focus and whether to add SEO or subscription features later.
- What’s the update frequency and content volume of each column? Weekly posts, or irregular sporadic updates? Are references manually curated, or auto-scraped from third-party platforms? This determines the content management approach.
- How should “Curated Articles” be presented? A card per article (title + source + short summary + external link), or just a link list? Do you need a fixed card template?
- Are “Personal Blog” posts long or short? Long posts may need detail pages, tables of contents, and reading progress. Short posts can just be listed directly.
- What form should “AI mini-apps” for lead generation take? Pure front-end interaction, or does it require a backend API? Do results need to be saved or shared? This determines technical complexity and whether the server needs a backend.
- Content form of the Humanities column. History, culture, travel — travelogues, reading notes, or historical essays? Any image display needs?
- Mobile priority. Do users mostly access from phones or computers? This affects layout design trade-offs.
- Should the three column pages share a unified structure? All “top intro + three sub-modules,” differing only in theme color and copy? Or does each column have its own unique layout?
- How should blog posts be written? Markdown files in the project, or a CMS?
- Do you need comments, subscriptions, or search? These are later features, but leave room for them in initial planning.
- Should quiz data be saved? If it’s just local scoring, pure front-end is enough, and server load is much lighter.
2. Tech Selection Matters — Plan Before You Move
There are many front-end + light-interaction paths. My requirement was each column independently configured, with minimal coupling. Based on this premise:
- Ruled out Gradio: essentially a rapid demo tool, not suitable for content sites.
- Ruled out HTML + CSS + JS: high maintenance cost; things get out of control as content grows.
- Considered Astro and Hugo.
Astro has mature Markdown/MDX support. Third-party article references can be embedded with MDX directly, or maintained as simple card components. If you later want a CMS, there are ready integrations. One caveat: Astro’s build speed is slower than Hugo, but for a site of this size, that’s negligible.
I also evaluated Hugo. Hugo’s core advantages are speed and minimalism: single binary, no dependencies, smooth Markdown writing experience, clear configuration. But Hugo’s limitation is that for modules requiring deep interaction — psychology quizzes, AI mini-apps — it’s less flexible than Astro. You’d need iframes or external JS, increasing coupling.
Final choice: Astro.
3. Cloud Deployment Is a Must — Plan the Cloud Approach Early
There are two deployment directions.
Option 1: ECS Cloud Server (more flexible)
Buy an ECS in a mainland China region, install Nginx or Caddy, upload the dist folder built by Astro, and configure DNS. The advantage: if the psychology quiz or AI mini-app later needs a lightweight backend (e.g., calling an API with a hidden Key), this server can handle it directly. ICP filing also depends on this ECS.
Option 2: OBS Static Hosting (lighter)
OBS supports static website hosting directly: create a bucket, upload files, enable “Static Website Hosting,” bind a custom domain. No server maintenance needed, billed by storage, requests, and traffic. Low cost when traffic is small. The downside: only pure static content; dynamic features need another solution.
Final recommendation: use ECS. ICP filing binds to this server, and future expansion is easier. OBS can serve as a CDN origin or backup later. ECS selection is critical; better scalability matters a lot down the road.
A pitfall I hit: I once considered deploying the Astro build to Cloudflare Pages (free), with static assets distributed by Cloudflare’s global edge nodes. Mainland access to Cloudflare can be significantly improved via optimized CNAME/IP. Hong Kong VPS as origin or direct hosting typically gives 30–50ms latency for mainland users. But after much tinkering, I realized: picking a single cloud vendor for compute + storage + build + hosting is the most efficient. It costs a bit more, but compared to post-deployment tinkering, that investment is trivial.
4. Start with the End in Mind
Take the “Curated Third-Party Articles” design. The site can’t be overly complex early on, and third-party content is mainly for lead generation. But you must consider the user journey — don’t let users bounce out of your site immediately after clicking.
Three approaches:
Approach 1: Open in a new tab
Use target="_blank". The browser opens a new tab; your site stays in the original tab. When users finish reading, closing the new tab brings them back. This is the most common approach for content sites — simple, no side effects.
Approach 2: Add a “back” cue
Add a small arrow icon next to external links, hinting “this is an external link, opens a new page.” Users have expectations and don’t feel interrupted.
Approach 3: Interstitial page
Clicking jumps to an intermediate page saying “You’re about to leave this site, heading to XXX,” with auto-redirect after a few seconds or requiring confirmation. This is heavier, typically used when explicit notification is needed. Rarely used for personal content sites.
Combined recommendation: Approach 1 + Approach 2. External links open in new tabs, with a small external-link icon so users know “this goes out.” This way you don’t lose users, and you have clear visual cues.
Another example: hierarchical content design. For each column, design the journey as:
Third-party article lead-in → Personal blog for awareness → AI mini-app/interaction for elevation.
First external curated content, then your original posts, finally interactive experiences. The logic moves from “light” to “heavy.”
5. Open-Source Ecosystem Compatibility — Features Never End, But There’s Always a Way
Version conflicts during development usually fall into three categories.
1. Node.js Incompatible with Astro Itself
This is the most direct error, usually caused by Astro’s underlying Node.js version requirement changing after an upgrade.
Typical scenario: a project runs fine locally, but fails during CI build with an error saying the current Node.js version isn’t supported. For example, Astro 6 requires Node.js >= 22.12.0; if the environment is Node 20, it fails.
Recommended solution: For clear version-requirement errors, check the engines field in package.json or the corresponding upgrade docs, then switch the Node.js environment accordingly.
2. Node.js Incompatible with Dependency Packages (Plugins)
This is more common but subtler. A third-party package the project depends on hasn’t adapted to the Node.js version in use.
Typical scenario: you habitually upgrade local Node.js to the latest (say v24), then the console floods with EBADENGINE warnings, saying some deep dependency only supports up to Node 22.
Recommended solution: Don’t blindly chase the latest Node.js. For blog-type projects, Node.js LTS (Long Term Support) usually offers the best compatibility. If warnings don’t affect running, ignore them temporarily. If they break the build, switch Node.js back to a more mature version.
3. Cascading Limits from Ecosystem Tooling
Astro depends on Vite and various official adapters (like @astrojs/node), and their Node.js requirements “propagate” to the project.
Typical scenario: you use the Node.js adapter, but find Astro core and the adapter disagree on Node version requirements, causing build errors.
Recommended solution: Keep Astro and its official adapters in sync. When upgrading Astro, remember to update @astrojs/node and other adapters too — they’re usually guaranteed compatible within the same version cycle.
Another example. In Astro, “images in the same directory as the article” has no official out-of-the-box solution. Mainstream static site generators mostly use these patterns:
- Images in
public/orstatic/: writing and images separated, zero config - Images in
src/assets/: writing and images separated, optimized at build - Images on a CDN: writing and images separated, not restricted by project structure
“Images alongside articles” is common in local writing tools (Obsidian, Typora) but rare in site build tools, because site builds need image optimization, compression, and format conversion — unified management is more convenient.
Ultimately I adopted a compromise: name blog content and blog images in a corresponding way, but they remain in two directories. A small regret — hoping a future Astro release fixes this small bug. For example:
- Article:
src/content/tech/zh/YYYY-MM-DD-llm-engineering-notes.md - Image:
public/images/tech/zh/YYYY-MM-DD-llm-engineering-notes-cover.jpg
When Astro renders, it uses the MD filename by default. A small trick: process the filename with a function to automatically strip the date, making existing and incremental content easy to scan. A minor optimization.
6. Make Good Use of MaaS / Tokens — Don’t Reinvent the Wheel
When designing the mini-app, I first thought of hardcoding the algorithm, but this kind of test mini-app is low-quality, too trivial, and poor at lead generation and retention. So I decided to bring in dynamic generation via a large model API — different questions each time, better interpretation of results.
A natural path is to find a model on Hugging Face for the mini-app; the appeal is “fun” and “out of the box.” But several details need consideration:
- Model size and load time: The site is a static Astro site deployed on ECS. If you load an HF model directly in the front end (say via Transformers.js), users download tens to hundreds of MB on first visit.
- Is it really “pure front-end”? Running the model in the user’s browser truly requires WebGPU. Chrome and modern browsers support it, but Firefox is still experimental by default, and mobile support is incomplete. Users come from different devices — compatibility is a problem.
- Fallback and cost: A more solid approach is HF Spaces’ Serverless API. You deploy the model on HF and your site calls it via API. But this involves API quota — HF’s free inference requests have rate limits, possibly insufficient for lead generation. Higher quota requires HF Pro.
Weighing all factors, I settled on “no local deployment, call via API,” using a MaaS approach. It fits perfectly:
- Out of the box: Preset mainstream models like GLM and DeepSeek, one-click activation, no self-hosting or ops.
- Pay-as-you-go: Billed by actual Tokens used, no cost when idle. Great for early-stage low-traffic lead-gen tools.
- Ecosystem closure: Site deployment and model calls both run on the same cloud vendor, unifying the tech stack and simplifying management.
A small trick: For the quiz questions, I adopted a more robust approach — “static skeleton + dynamic content”:
- Fixed question structure: 7 questions, 4 options each, option scores 1–4
- Dynamic question content: The model only generates “7 questions fitting the emotion self-assessment theme,” returning structured data (JSON)
- Fixed scoring logic: Local scoring, model doesn’t participate, avoiding model arithmetic errors
- Dynamic interpretation: Send total score + user answers to the model, let it generate a personalized interpretation
This way, the model only does what it’s good at (generating text) and avoids what it’s not good at (precise scoring). Quality is controllable, speed is acceptable.
7. Closing Thoughts
Recently I saw an interesting data point from a randomized controlled trial by METR, a nonprofit. They had 16 senior open-source developers work on 246 real tasks from their own projects (averaging about 2 hours each), randomly assigned whether AI could be used. The result is counterintuitive:
- Measured 19% slower: When AI was allowed, completing tasks took 19% longer on average.
- Felt 20% faster: Before the experiment they predicted a 24% speedup. Even after measurement proved they were slower, they still felt AI sped them up by 20% afterward.
Why this bias?
In complex projects you know extremely well, AI can actually become a burden:
- High interaction cost: Writing prompts, reviewing code, waiting for results, correcting errors — this “communication” time eats into actual coding time.
- Familiarity backlash: Senior developers have their own “flow” with the codebase; AI intervention disrupts the rhythm. Time spent judging “is the AI right?” is slower than just writing it yourself.
- Complex projects resist: The experiment used open-source libraries maintained for 10 years with over a million lines of code. Projects with many implicit rules — AI often misses the point.
This conclusion is specific to senior developers working on extremely familiar complex projects. If you’re learning something new, building rapid prototypes, or maintaining unfamiliar codebases, AI’s “perceived speedup” and actual effect may both be much better.
This National Day holiday, I spent two days, using Astro, JSON, TS, JS, MD, and more — 8000+ lines of code, AI spec coding — letting someone who never loved programming much experience AI-assisted coding speedup. Overall, it’s worth looking forward to. Space is limited; much wasn’t detailed. Everyone can practice themselves — practice reveals truth.