Build a Personal Website with VitePress, GitHub, and Cloudflare Pages
Blogging has been around for years. We have gone from hosted services such as Wretch and PIXNET to the greater freedom of WordPress, but completely owning a personal blog has never been especially easy.
Use a hosted service and you have to follow its rules—and you cannot stop the platform from placing ads on your site. Skip the hosted service and you need to run the site yourself, which means renting a server, buying a domain, and building the project. Both options can be pretty discouraging for people who want to build a personal brand but lack the experience, or have the skills but not much spare time.
Fortunately, the barrier has become lower in recent years. The combination used here—VitePress + GitHub + Cloudflare Pages—makes a very lightweight personal blog. It will not build a huge, complicated site, but it is a good place to start blogging: write a few articles first, keep things simple and fast, and avoid most maintenance work. If the site grows later, you can keep your domain and move elsewhere. Plenty of room to advance or retreat.
Who is this setup for?
You will touch some code and development tools, so a little engineering experience helps. None of it goes very deep, though, and beginners who are happy to learn as they go should be fine.
This setup is especially useful if you:
- Want to manage articles in Markdown.
- Already use Git, or want to start learning it.
- Want a personal site without accounts, a shopping cart, or a complicated dashboard.
- Want low maintenance while keeping control of the content and domain.
The services we will use
VitePress
VitePress is a lightweight foundation for a website. It lets you put together a basic publishing site quickly.
Pages are managed in Markdown, the final output is a static site, and it is free. The downside is that it has far fewer ready-made resources than WordPress. There is no giant collection of fancy layouts and plugins waiting for you, so more complicated features still need some development work.
GitHub
GitHub is a well-established version-control service. This time it does more than version control: Cloudflare Pages also uses it to publish updates automatically.
GitHub is used everywhere. Even if you never finish the blog, there is a good chance you will use it in another project, so learning it is still a win.
Cloudflare Pages
Cloudflare Pages is the hosting service used in this guide. Compared with renting a server and setting everything up yourself, Cloudflare has already packaged most of the work into services that are quick to use.
Cloudflare also provides DNS and domain services, so you can buy a domain and host the site in one place. If you do not buy a domain, you can use the free address provided by Pages.
How publishing works
- Create a VitePress project.
- Track the project with Git and push it to GitHub.
- Import the GitHub repository into Cloudflare Pages.
- Configure the build command and output directory.
- Use the Pages domain or connect your own domain.
- Every future push triggers a new Cloudflare deployment.
Install Node.js
Install Node.js first, because the pnpm commands used later depend on it. Download a currently supported LTS release from the official Node.js website.
After installation, open Command Prompt, PowerShell, or a terminal and check the versions:
node -v
npm -vIf both commands print a version number, you are good to go.
Install pnpm
Next, install pnpm:
npm install -g pnpm
pnpm -vCreate a VitePress project
Create a folder for the blog, or do it directly from the terminal:
mkdir blog
cd blogInstall VitePress:
pnpm add -D vitepressIf the build fails because pnpm's security policy blocked esbuild, follow the terminal message and run:
pnpm approve-buildsSelect esbuild when prompted. Only approve packages you recognize—do not blindly select everything. Then initialize VitePress:
pnpm vitepress initChoose the default VitePress theme and let the wizard add npm scripts to package.json. It will create files such as .vitepress/, index.md, and package.json.
Preview the site locally
Run:
pnpm docs:devThe terminal will display a local URL, usually:
http://localhost:5173Open it in a browser and you should see the default VitePress home page. Changes to Markdown will update automatically.
Before deployment, it is also worth running a production build once:
pnpm docs:build
pnpm docs:previewCreate a Git repository
If Git is not installed, download it from the official Git website. This article will not go deeply into Git; there are already plenty of good tutorials available if you need one.
After installation, configure the basic identity used for commits:
git config --global user.name "Example"
git config --global user.email "example@example.com"A public repository may show this information in its commit history. GitHub provides a noreply address if you do not want to publish a private email address.
Move the terminal into the blog project and initialize Git:
git init -b mainCreate a .gitignore file in the project root so Git does not track things it does not need:
node_modules/
.vitepress/cache/
.vitepress/dist/
dist/Add the files and create the first commit:
git add .
git commit -m "Initial VitePress project"Push the site to GitHub
Create an empty repository on GitHub. It is easier if you do not initialize it with a README, license, or .gitignore yet.
Connect the local project to GitHub and push main:
git remote add origin https://github.com/example/example-blog.git
git push -u origin mainIf you accidentally committed node_modules before setting up .gitignore, adding the ignore rule is not enough because Git is already tracking those files. Run:
git rm -r --cached node_modules
git commit -m "Remove node_modules from repository"
git pushThis only stops Git from tracking node_modules. It does not delete the installed packages from your computer.
Deploy to Cloudflare Pages
Sign in to Cloudflare and open Workers & Pages. Cloudflare currently puts more emphasis on Workers, so make sure you do not accidentally create a Worker when you want a Pages project. Find the Pages setup and choose the option to import an existing Git repository.
The exact interface may change, but the basic flow is to connect GitHub, select the repository you just created, and enter the build settings.
This project puts VitePress directly at the repository root, so use:
Production branch: main
Build command: pnpm docs:build
Build output directory: .vitepress/dist
Root directory: /If your VitePress project is inside a subdirectory, adjust the root and output paths instead of copying these settings exactly.
Save the settings and start the first deployment. If it works, Cloudflare provides a public address similar to:
https://example-blog.pages.devIf the build fails, check the deployment log first. Common causes include incompatible Node.js or pnpm versions, a mistyped build command, the wrong output directory, or an accidentally committed node_modules directory.
Connect a custom domain
The supplied pages.dev address is already public. If you are only testing or experimenting, you can stop here.
If you want to build a long-term brand, consider buying a domain and adding it under Custom domains in the Pages project. A domain is basically a fixed address of your own. It has an annual fee, but it helps when you plan to keep the site around.
If Cloudflare also sells and manages the domain, the DNS setup can usually be completed in the same flow. The actual price depends on the domain name and top-level domain.
Publishing future articles
Once the site is ready, you only need to write Markdown, check that the local build works, and push it:
git add .
git commit -m "Publish a new article"
git pushCloudflare Pages will build and deploy the new version automatically. There is no need to upload files by hand every time.
Conclusion
VitePress + GitHub + Cloudflare Pages requires almost no maintenance. It is obviously not the right tool for a huge and complicated website, but it is a light and comfortable setup for a technical blog—and it is the setup this blog ended up choosing.
Writing a few articles first is more practical than trying to finish every feature on day one. The site can grow or move later. There is still plenty of room to advance or retreat.
English translation provided by Codex.