I have a next.js 13 app and want to add an API endpoint /api/getIP
.
The route.js
file is in the /app/api/getIP/route.js
.
Minimal Reproduceable Code: https://github.com/Nusab19/nextjs-test/tree/main/app
I tried several ways of doing it but none of them worked. I tried using request-ip
to get the ip but it returned null
.
Here is my code:
import { NextResponse } from "next/server";
import requestIp from "request-ip";
export async function GET(req) {
const detectedIp = requestIp.getClientIp(req);
const data = {
ok: true,
ip: detectedIp,
userAgent: req.headers.get("user-agent"),
};
return new NextResponse(JSON.stringify(data, null, 2));
}
I get this response when I visit:
{
"ok": true,
"ip": null,
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36"
}
Since you are already using Next.js app
router, I'm assuming you are hosting on Vercel.
If yes, Vercel can provide these information by using a Next.js Middleware.
ip: (string || undefined) - Has the IP address of the Request. This information is provided by your hosting platform.
https://nextjs.org/docs/pages/api-reference/functions/next-server#nextrequest
You can create a Next.js app
middleware by creating the file middleware.js
at the root of your repo (if you are using src/app
, then it should be src/middleware.js
), with content:
import { NextRequest, NextResponse } from 'next/server';
export async function middleware(req: NextRequest) {
const { ip, nextUrl } = req;
nextUrl.searchParams.set('clientIp', ip);
return NextResponse.rewrite(nextUrl);
}
The above code will add the clientIp
as a query param and then pass it your route handler.
Within your route handler, you can access it like:
export async function GET(req) {
const data = {
ok: true,
ip: req.query?.clientIp ?? "127.0.0.1",
message: "Hello from the API",
};
return new NextResponse(JSON.stringify(data, null, 2));
}
The downside is that, it wont work in your local environment (you know your local ip anyway) and any hosting platforms that do not provide this information.
If you dont want to use a middleware, you can use the request headers to retrieve the ip.
export async function GET(req) {
const data = {
ok: true,
ip: req.headers.get("x-real-ip") ?? "127.0.0.1",
message: "Hello from the API",
};
return new NextResponse(JSON.stringify(data, null, 2));
}