Ship an Astro content site to production
Scaffold, build and deploy a static Astro blog to Netlify. Covers zero-config builds, custom domains and HTTPS, plus Cloudflare Pages and Vercel.
Before you start
- Node.js version 22.23.4 or higher installed locally
- npm package manager version 10.9 or later
- Git installed and configured with a remote provider like GitHub
- A Netlify account (free Starter plan is sufficient)
Astro is a web framework built for content-heavy sites such as blogs, marketing sites, documentation, and agency portfolios. It pre-renders Markdown and MDX into static HTML, so pages score well on Lighthouse with no client-side JavaScript overhead by default.
This guide walks through creating an Astro content site from scratch, checking the local static build, and deploying to Netlify with a custom domain and automatic HTTPS. It also covers alternative hosting on Cloudflare Pages and Vercel.
1. Prerequisites and local environment setup
Before you start, confirm that your local environment has the required runtime and tools. Astro v7 requires a recent LTS release of Node.js.
Check your installed Node.js and npm versions:
node -v
npm -v
If your Node.js version is below 22.23.4, update it using your system node version manager:
nvm install 22.23.4
nvm use 22.23.4
You will also need a free account on Netlify or an equivalent modern static hosting platform, and a GitHub, GitLab, or Bitbucket account to host your Git repository.
2. Scaffolding the Astro content site
Astro provides a scaffolding tool, create-astro, that sets up a working project. For content sites, the blog template includes MDX support, an RSS feed, and an XML sitemap.
Run the scaffolding command without prompts from your projects folder:
npm create astro@latest astro-content-site -- --template blog --install --no-git --yes
This command does the following:
- Copies the official Astro blog template into the
astro-content-sitedirectory. - Sets up the content collections schema in
src/content.config.ts. - Adds the
@astrojs/mdxand@astrojs/sitemapintegrations inastro.config.mjs, and an RSS endpoint insrc/pages/rss.xml.jsthat uses@astrojs/rss. - Installs the dependencies listed in
package.json, including thesharpimage processing library.
For more details on initial project creation options and all create astro flags, consult the official Astro install and setup guide.
3. Testing the local build
Before you push to a hosting provider, check that the site builds cleanly into static HTML.
Navigate into the project directory:
cd astro-content-site
Run the local production build command:
npm run build
Astro invokes astro build to parse your content collections, optimize local images used with the <Image /> component, pre-render all static route pages, and generate an XML sitemap index.
Verify that the dist directory has been created and contains index.html:
ls -la dist/index.html
You should see dist/index.html along with static route directories such as dist/blog/ and dist/about/. You can preview the production build locally with Astro's built-in preview server:
npm run preview
Open the address printed in the terminal to check the output. When you are done, stop the preview server with Ctrl+C.
4. Connecting a Git repository
Static hosting platforms build automatically whenever you push commits to the remote repository.
Initialize a Git repository and commit your source files:
git init
git add .
git commit -m 'Initial commit of Astro content blog'
Create a new repository on your preferred Git host (for example, GitHub) and push your branch:
git remote add origin [email protected]:your-username/astro-content-site.git
git branch -M main
git push -u origin main
We did not run this step for this guide.
5. Configuring Netlify build and deploy settings
Netlify deploys static Astro sites without custom plugins or edge adapters.
Dashboard setup
To connect your repository through the Netlify web dashboard:
- Log in to Netlify and select
Add new site>Import an existing project. - Connect your Git provider (GitHub, GitLab, or Bitbucket) and authorize Netlify.
- Select your
astro-content-siterepository. - Netlify will analyze your project structure and suggest default build settings.
Configure the build parameters as documented in the Netlify Configure Builds Overview and the Astro Netlify Deployment Guide:
- Base directory: Leave blank (repository root).
- Build command:
npm run build(orastro build). - Publish directory:
dist.
Click Deploy site. Netlify assigns your project a temporary live subdomain formatted as random-name-12345.netlify.app.
Configuration via netlify.toml
Alternatively, you can declare your project settings directly in version control by adding a netlify.toml file to your repository root:
[build]
command = "npm run build"
publish = "dist"
[build.environment]
NODE_VERSION = "22.23.4"
When Netlify reads a root-level netlify.toml, a base directory set in that file overrides the dashboard setting.
We did not run this step for this guide.
6. Configuring a custom domain and automatic HTTPS
Once your site deploys cleanly on the default Netlify subdomain, you can connect a production custom domain (such as www.example.com).
Setting up DNS
Follow the steps outlined in the Netlify Custom Domains Guide:
- In your Netlify project overview, select
Domain managementin the left sidebar. - Click
Add a domainand input your registered domain name. - If using an external registrar (e.g., Namecheap, Cloudflare, or Porkbun), create the required DNS records:
- For subdomains like
www.example.com: Add aCNAMErecord with namewwwpointing toyour-site-name.netlify.app. - For apex root domains like
example.com: Use Netlify DNS, or an ALIAS or CNAME-flattening record if your DNS provider supports it.
- For subdomains like
Automatic HTTPS certificates
As documented in Netlify Secure Domains with HTTPS, Netlify enables HTTPS on all sites, including automatic certificate creation and renewal:
- Netlify provisions a free certificate from Let's Encrypt when you add a custom domain.
- Certificate creation is automatic after you add the domain.
- Renewal of Netlify-provisioned certificates is automatic. Custom certificates that you upload must be renewed manually.
We did not run this step for this guide.
7. Alternative deployments: Cloudflare Pages and Vercel
If you need multi-cloud redundancy or integration with other platforms, Astro's static output also deploys elsewhere.
Cloudflare Pages
Cloudflare Pages can host the static output of an Astro site. As detailed in the Cloudflare Pages Astro Deployment Guide:
- In the Cloudflare dashboard, go to
Workers & Pagesand create a Pages project connected to your Git repository. - Select your
astro-content-siterepository. - In build settings:
- Build command:
npm run build - Build output directory:
dist
- Build command:
- Click
Save and Deploy.
For custom domains on Cloudflare Pages, open the custom domains section of your Pages project and enter your domain name, as described in Cloudflare Pages Custom Domains Documentation. If your domain has CAA records, they must allow Cloudflare to issue a certificate for it.
We did not run this step for this guide.
Vercel
Vercel deploys static Astro sites with zero configuration, as the Astro Vercel Deployment Guide describes:
- Import your GitHub repository in the Vercel dashboard.
- Vercel automatically detects Astro and configures the build settings.
- Click
Deploy.
To add a domain on Vercel, open Settings > Domains for your project and follow the DNS instructions documented in Vercel Custom Domains Guide.
We did not run this step for this guide.
8. Common troubleshooting and fixes
These are fixes for common problems when deploying static Astro sites.
Problem 1: Build fails with unsupported Node.js engine
- Symptom: The remote build log reports that the installed Node.js version is not supported by Astro, which requires version 22.23.4 or higher.
- Cause: The deployment environment uses a Node.js version below 22.23.4.
- Fix: As detailed in Netlify Dependency Management, set the
NODE_VERSIONenvironment variable in your dashboard or add a.node-versionfile to the root of your repository containing22.23.4.
Problem 2: 404 not found on root or subpages after deploy
- Symptom: The build finishes without errors, but visiting your live site URL displays Netlify 404 page.
- Cause: The publish directory setting in Netlify is set to
public,build, or left blank instead ofdist. - Fix: Review Netlify Configure Builds Overview and update your publish directory to
distin your site's build settings.
Problem 3: Client scripts cannot access environment variables
- Symptom: Client-side interactive scripts log
undefinedwhen reading environment variables viaimport.meta.env.KEY. - Cause: Astro exposes environment variables without the
PUBLIC_prefix only to server-side code, not to client-side scripts. - Fix: According to Astro Environment Variables Guide, prefix any variable needed in the browser with
PUBLIC_(for example,PUBLIC_ANALYTICS_ID).
Problem 4: SSL certificate generation stalls on custom domain
- Symptom: Your custom domain loads via HTTP but fails on HTTPS or displays a certificate warning.
- Cause: DNS changes have not fully propagated globally, or existing DNS CAA records at your registrar restrict certificate authorities from issuing certificates.
- Fix: Per Netlify Secure Domains with HTTPS, ensure your DNS records resolve to Netlify, allow time for propagation, and if your DNS zone includes CAA records, confirm they allow letsencrypt.org to issue certificates.
Expected result: A production-ready static site generated into the dist directory containing pre-rendered HTML, optimized WebP images, RSS feed, and sitemap index.
If something goes wrong
| Problem | Fix |
|---|---|
| Build fails during deployment with unsupported Node.js engine error | Set the NODE_VERSION environment variable or add a .node-version file in repository root to match Node >=22.23.4docs.netlify.com |
| Site deploys successfully but returns 404 or empty directory listing on visit | Ensure publish directory is explicitly set to dist in host dashboard settings or netlify.tomldocs.netlify.com |
| Client-side scripts cannot access custom environment variables | Prefix environment variables with PUBLIC_ so Astro bundles them into client-side scriptsdocs.astro.build |
| Custom domain reports certificate issuance failure or pending status | Check that DNS records point to Netlify and, if your domain has CAA records, make sure they allow letsencrypt.org to issue certificatesdocs.netlify.com |