Moving Blog Comments From Disqus to Waline: Free Setup With Vercel + Neon, and What Went Wrong
I replaced Disqus with Waline on my blog, hosted for free on Vercel and Neon. Here is why I switched, how I set it up, and where I got stuck on Netlify.
While rebuilding my blog, I also replaced Disqus, which I had used for years, with Waline.
It was bumpier than I expected, including a long detour on Netlify. This post covers why I chose Waline, the setup steps, and the traps I fell into.
Why I left Disqus
- Ads: the free plan puts ads in the comment section, and there are more of them every year.
- Slow: it loads a lot of extra tracking scripts.
- Can't be restyled: my new blog has a notebook look, and Disqus sticks out.
- The comments aren't mine: they all live on Disqus's platform.
Options I considered
| Option | Do readers need to log in? | Downsides |
|---|---|---|
| Disqus with guest comments | No | Ads, slow, doesn't match the site |
| Giscus | Yes, a GitHub account | Most of my readers don't have one |
| Google Form + a sheet | No | No threads, no notifications, spam is on you |
| Waline | No, just a nickname | You host the backend yourself |
Many of my readers arrive from searches about visas and working holidays, so the lower the barrier to commenting, the better. That ruled out anything that needs a GitHub account.
I went with Waline because:
- A nickname is all you need to comment
- No ads
- Comments are stored in my own database and can be exported any time
- Replies, email notifications, spam filtering and a moderation panel are built in
- The look can be changed with CSS to match the site
How Waline is put together
Waline has three parts:
- Client: the comment box under each post (
@waline/client) - Server: the program that handles comments, deployed on Vercel
- Database: where comments are stored — I use Neon (free PostgreSQL)
Waline itself is free and open source, and the free plans of Vercel and Neon are enough for a personal blog's comments.
Setup
1. Create the database on Neon
Create a project on Neon. Postgres is the only service you need.
Then open the SQL Editor, paste Waline's official PostgreSQL schema (waline.pgsql) and run it. You end up with three tables: wl_comment, wl_counter and wl_users.
2. Deploy the server to Vercel
Use the Deploy button in Waline's official docs. It creates a new repo and a Vercel project for you.
3. Add environment variables
In the Vercel project, go to Settings → Environment Variables and add the database connection details:
PG_HOST=your host
PG_DB=database name
PG_USER=user
PG_PASSWORD=password
PG_PORT=5432
PG_SSL=trueThe values come from splitting Neon's connection string:
postgresql://user:password@host/database?sslmode=requireAfterwards, go to Deployments and hit Redeploy — the variables only take effect after a redeploy.
4. Register the admin account
Open your-server-url/ui/register and sign up. The first person to register becomes the admin, so do it right after deploying. From then on you moderate and delete comments at /ui.
5. Connect it to the blog
Install the client:
npm install @waline/clientPut a container on the post page and only load Waline when it is about to scroll into view, so it doesn't slow down the post itself:
import('@waline/client').then(({ init }) => {
init({
el: container,
serverURL: 'https://your-server.vercel.app',
path: '/en/blog/nz/buy-car', // each post's URL path is its thread key
lang: 'en',
meta: ['nick', 'mail'],
requiredMeta: ['nick'], // only the nickname is required
})
})The styling is done through Waline's CSS variables: swap the borders and button colour for the site's ink lines and red, and it fits right into the notebook look.
I also kept a fallback: if the Waline server URL isn't configured, the post page shows the old Disqus embed, so comments never break during the switch.
What went wrong
Trap 1: on Netlify, everything was Not Found
My blog is hosted on Netlify, so at first I wanted the Waline server there as well and followed the official Netlify guide.
The deploy succeeded, but opening the server URL showed a single line: Not Found. Same for the admin page.
It took a long time to find the cause. Netlify bundles the server into a single file, but Waline reads its own source files at runtime — after bundling those files are gone, so it doesn't recognise any URL. Telling Netlify not to bundle it and ship everything as-is fixed the routing, but the package was close to 400MB, over Netlify's 250MB function limit, so it still couldn't deploy.
In the end I switched to Vercel and it worked first time. Waline's server package is literally called @waline/vercel — that is the platform it mainly supports.
Takeaway: put the Waline server on Vercel and don't waste time on Netlify. Hosting the blog itself on Netlify is fine; just keep the two separate.
Trap 2: PG_PORT is not optional
Neon's connection string doesn't include a port, because 5432 is PostgreSQL's default. But Waline's default port is not 5432, so you have to add PG_PORT=5432 yourself.
Trap 3: a stray line break in an environment variable
The server was running but comments wouldn't save. The error was:
database "
neondb" does not existLook closely and there is a line break before neondb. I had picked it up while pasting the variable, so the database name became "line break + neondb" — which of course doesn't exist. Clearing the value and typing it by hand fixed it.
Trap 4: you don't need Neon's setup commands
After creating a project, Neon shows a list of commands for "setting up Neon in your project". Those are for people who connect to the database from their own code. The blog never talks to the database — the Waline server does — so you can skip them.
Settings worth adding
SECURE_DOMAINS: set it to your own domain so other sites can't use your server.COMMENT_AUDIT=true: turn this on if you want to approve comments before they appear.
Was it worth it
The comment section finally looks like the rest of the site, and nobody has to log in to leave a comment.
The only cost is that the server is mine to look after: every so often I need to update it on Vercel. Compared with seeing ads every time I open a post, I think that's a good trade.
If you're thinking of leaving Disqus too, I hope this saves you a few wrong turns. Feel free to try out the new comment box below!
Related Posts
Quickly Connect Your Porkbun Domain to Netlify in 5 Minutes
A super detailed guide to quickly connect your Porkbun purchased domain to Netlify in under 5 minutes, making website deployment easy!


