You can add a blog to a Next.js app on Vercel without building blog pages, a CMS or a database. One middleware file rewrites every request under /blog to your Rankwise blog. Readers and search engines see yourdomain.com/blog, and your app keeps every other route.
This guide covers:
- What you need
- Step 1: Create the blog in Rankwise
- Step 2: Add the middleware file
- Step 3: Set the token on Vercel
- Step 4: Deploy and check
- Next.js 16 and proxy.ts
- Troubleshooting
At the end, your blog lives at yourdomain.com/blog with its own sitemap, RSS feed and llms.txt.
What you need
- A Rankwise account. The free blog is enough. It covers 10,000 visits a month.
- A Next.js app that you deploy on Vercel, with your domain connected to the Vercel project.
- A free path. Your app must not already have pages under /blog. This guide uses /blog.
The middleware also runs on a Next.js app you host yourself on a Node.js server or in Docker. It does not run on a static export (output: "export"), because the Next.js docs list static export as unsupported for this file.
Step 1: Create the blog in Rankwise
- Sign up for Rankwise. On the free blog page, choose Put it on my own domain at /blog instead.
- Open the setup for the blog. Choose On my own site.
- Choose A path, like /blog.
- Enter the blog name, one line about the blog, your website (for example https://yourdomain.com) and the path, for example /blog.
- Click Create my blog.
- Rankwise shows three snippets. Pick Next.js (Vercel) and copy it.
The token is in the last line of the snippet. Rankwise shows it only once, so copy the whole snippet before you leave the page.
This guide covers a blog at a path. To put the blog on a subdomain like blog.yourdomain.com, choose A subdomain, like blog.yourdomain.com instead. The snippet then forwards every path on that host, so copy it from the app rather than from this page.
Step 2: Add the middleware file
Create middleware.ts at the root of your Next.js app, next to the app or pages folder (inside src if your app uses one). Paste the snippet from Rankwise. It looks like this, with your own blog id:
// middleware.ts at the root of your Next.js app.
import { NextResponse, type NextRequest } from "next/server"
const PREFIX = "/blog"
const UPSTREAM = "https://rankwiseblog.com/hosted/YOUR-BLOG-ID"
const TOKEN = process.env.RANKWISE_BLOG_TOKEN ?? ""
export function middleware(request: NextRequest) {
const { pathname, search, host } = request.nextUrl
const rest = pathname.slice(PREFIX.length)
const headers = new Headers(request.headers)
headers.set("x-rankwise-blog-token", TOKEN)
headers.set("x-rankwise-forwarded-host", host)
headers.set(
"x-rankwise-visitor-ip",
(request.headers.get("x-forwarded-for") ?? "").split(",")[0].trim()
)
return NextResponse.rewrite(new URL(UPSTREAM + rest + search), {
request: { headers }
})
}
// Next.js needs literal values here.
export const config = {
matcher: ["/blog", "/blog/:path*"]
}
// Set this in your Vercel project settings:
// RANKWISE_BLOG_TOKEN=YOUR-TOKEN
Here is what each part does:
- The matcher runs the middleware only for /blog and the paths under it. Every other route in your app works as before.
- The rewrite fetches the page from your Rankwise blog and serves it at your address. The browser never leaves your domain.
- The headers tell Rankwise that the request comes from your app (the token) and which domain serves it (the host). The visitor's IP address, from
x-forwarded-for, lets Rankwise limit spam sign-ups to your newsletter form.
If your app already has a middleware file, Next.js uses one file per app. Add the blog branch to the file you have. Return the rewrite when pathname is /blog or starts with /blog/, and add both blog paths to your matcher.
Step 3: Set the token on Vercel
- Open your project on Vercel and go to Settings, then Environment Variables.
- Add
RANKWISE_BLOG_TOKENwith the token from the last line of the snippet. - Apply it to the Production environment, and to Preview if you want the blog in preview deployments.
Keep the token out of your code and out of git. The snippet reads it from the environment for that reason.
Step 4: Deploy and check
- Commit
middleware.tsand deploy. An environment variable reaches your app on the next deployment. - Open yourdomain.com/blog. You see your blog's index page.
- Back in Rankwise, click Check my blog. When Rankwise finds the blog on your page, it shows as connected.
To check that search engines may index the blog, run:
curl -sI https://yourdomain.com/blog/
The answer must not contain x-robots-tag: noindex. Rankwise sends that header when the token or the host does not match, so the copy on our server never competes with yours.
Next.js 16 and proxy.ts
Next.js 16 renamed the middleware file convention to proxy. The old name is deprecated. On Next.js 16 or later:
- Name the file
proxy.tsinstead ofmiddleware.ts. - Rename the function from
middlewaretoproxy.
Everything else in the snippet stays the same. The Next.js docs also offer a codemod that makes both changes: npx @next/codemod@canary middleware-to-proxy .
Troubleshooting
/blog shows my app's 404 page. The middleware file is in the wrong folder, or the matcher does not include /blog. The file must sit at the same level as app or pages.
The page loads, but the header says noindex. The token is empty or wrong. Check RANKWISE_BLOG_TOKEN on Vercel and redeploy. Also check that Your website in the Rankwise setup matches the domain your visitors use.
My app has its own /blog pages. Pick another path in Rankwise, such as /articles, and use the snippet Rankwise makes for that path.
Check my blog fails. Confirm that yourdomain.com/blog shows the blog, wait a minute, and try again.
Once the blog is live, every post you publish appears at yourdomain.com/blog with its sitemap entry, RSS item, llms.txt line and Markdown copy.