diff --git a/docs/02-app/01-building-your-application/11-upgrading/02-version-15.mdx b/docs/02-app/01-building-your-application/11-upgrading/02-version-15.mdx index 6fcb479bc6f68..337eff87f04b4 100644 --- a/docs/02-app/01-building-your-application/11-upgrading/02-version-15.mdx +++ b/docs/02-app/01-building-your-application/11-upgrading/02-version-15.mdx @@ -157,3 +157,31 @@ module.exports = nextConfig Auto instrumentation for Speed Insights was removed in Next.js 15. To continue using Speed Insights, follow the [Vercel Speed Insights Quickstart](https://vercel.com/docs/speed-insights/quickstart) guide. + +## `NextRequest` Geolocation + +The `geo` and `ip` properties on `NextRequest` have been removed. These values had to be provided by your hosting provider. + +If you are using Vercel, you can alternatively use the `geolocation` and `ipAddress` functions from [`@vercel/functions](https://vercel.com/docs/functions/vercel-functions-package) instead: + +```ts filename="middleware.ts" +import { geolocation } from '@vercel/functions' +import type { NextRequest } from 'next/server' + +export function middleware(request: NextRequest) { + const { city } = geolocation(request) + + // ... +} +``` + +```ts filename="middleware.ts" +import { ipAddress } from '@vercel/functions' +import type { NextRequest } from 'next/server' + +export function middleware(request: NextRequest) { + const ip = ipAddress(request) + + // ... +} +``` diff --git a/docs/02-app/02-api-reference/04-functions/next-request.mdx b/docs/02-app/02-api-reference/04-functions/next-request.mdx index fc8a8f89e2916..24c2f2e482bee 100644 --- a/docs/02-app/02-api-reference/04-functions/next-request.mdx +++ b/docs/02-app/02-api-reference/04-functions/next-request.mdx @@ -116,36 +116,8 @@ The following options are available: -## `ip` +## Version History -The `ip` property is a string that contains the IP address of the request. This value can optionally be provided by your hosting platform. - -> **Good to know:** On [Vercel](https://vercel.com/docs/frameworks/nextjs?utm_source=next-site&utm_medium=docs&utm_campaign=next-website), this value is provided by default. On other platforms, you can use the [`X-Forwarded-For`](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For) header to provide the IP address. - -```ts -// Provided by Vercel -request.ip -// Self-hosting -request.headers.get('X-Forwarded-For') -``` - -## `geo` - -The `geo` property is an object that contains the geographic information of the request. This value can optionally be provided by your hosting platform. - -> **Good to know:** On [Vercel](https://vercel.com/docs/frameworks/nextjs?utm_source=next-site&utm_medium=docs&utm_campaign=next-website), this value is provided by default. On other platforms, you can use the [`X-Forwarded-For`](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For) header to provide the IP address, then use a [third-party service](https://ip-api.com/) to lookup the geographic information. - -```ts -// Provided by Vercel -request.geo.city -request.geo.country -request.geo.region -request.geo.latitude -request.geo.longitude - -// Self-hosting -function getGeo(request) { - let ip = request.headers.get('X-Forwarded-For') - // Use a third-party service to lookup the geographic information -} -``` +| Version | Changes | +| --------- | ----------------------- | +| `v15.0.0` | `ip` and `geo` removed. | diff --git a/packages/next/src/server/web/adapter.ts b/packages/next/src/server/web/adapter.ts index 9076257aaf662..d322a669a9d45 100644 --- a/packages/next/src/server/web/adapter.ts +++ b/packages/next/src/server/web/adapter.ts @@ -151,9 +151,7 @@ export async function adapter( input: stripInternalSearchParams(normalizeUrl, true).toString(), init: { body: params.request.body, - geo: params.request.geo, headers: requestHeaders, - ip: params.request.ip, method: params.request.method, nextConfig: params.request.nextConfig, signal: params.request.signal, diff --git a/packages/next/src/server/web/spec-extension/request.ts b/packages/next/src/server/web/spec-extension/request.ts index 7e01e22a514d4..546ede47b201d 100644 --- a/packages/next/src/server/web/spec-extension/request.ts +++ b/packages/next/src/server/web/spec-extension/request.ts @@ -1,5 +1,4 @@ import type { I18NConfig } from '../../config-shared' -import type { RequestData } from '../types' import { NextURL } from '../next-url' import { toNodeOutgoingHttpHeaders, validateURL } from '../utils' import { RemovedUAError, RemovedPageError } from '../error' @@ -15,8 +14,6 @@ export const INTERNALS = Symbol('internal request') export class NextRequest extends Request { [INTERNALS]: { cookies: RequestCookies - geo: RequestData['geo'] - ip?: string url: string nextUrl: NextURL } @@ -33,8 +30,6 @@ export class NextRequest extends Request { }) this[INTERNALS] = { cookies: new RequestCookies(this.headers), - geo: init.geo || {}, - ip: init.ip, nextUrl, url: process.env.__NEXT_NO_MIDDLEWARE_URL_NORMALIZE ? url @@ -45,8 +40,6 @@ export class NextRequest extends Request { [Symbol.for('edge-runtime.inspect.custom')]() { return { cookies: this.cookies, - geo: this.geo, - ip: this.ip, nextUrl: this.nextUrl, url: this.url, // rest of props come from Request @@ -70,14 +63,6 @@ export class NextRequest extends Request { return this[INTERNALS].cookies } - public get geo() { - return this[INTERNALS].geo - } - - public get ip() { - return this[INTERNALS].ip - } - public get nextUrl() { return this[INTERNALS].nextUrl } @@ -106,12 +91,6 @@ export class NextRequest extends Request { } export interface RequestInit extends globalThis.RequestInit { - geo?: { - city?: string - country?: string - region?: string - } - ip?: string nextConfig?: { basePath?: string i18n?: I18NConfig | null diff --git a/packages/next/src/server/web/types.ts b/packages/next/src/server/web/types.ts index 1132da6bfd2fb..85412d0f72edc 100644 --- a/packages/next/src/server/web/types.ts +++ b/packages/next/src/server/web/types.ts @@ -9,15 +9,7 @@ import type { FetchMetrics } from '../base-http' export type { MiddlewareConfig } from '../../build/analysis/get-page-static-info' export interface RequestData { - geo?: { - city?: string - country?: string - region?: string - latitude?: string - longitude?: string - } headers: OutgoingHttpHeaders - ip?: string method: string nextConfig?: { basePath?: string diff --git a/test/unit/web-runtime/next-request.test.ts b/test/unit/web-runtime/next-request.test.ts index deedeb6b38d68..817866710c649 100644 --- a/test/unit/web-runtime/next-request.test.ts +++ b/test/unit/web-runtime/next-request.test.ts @@ -13,9 +13,6 @@ it('should allow the 2nd parameter to be undefined', () => { const request = new NextRequest('https://vercel.com') expectTypeOf(request).toMatchTypeOf() - expect( - new NextRequest('https://vercel.com', { geo: { city: 'Mars' } }) - ).toHaveProperty('geo.city', 'Mars') expect(new NextRequest('https://vercel.com')).toHaveProperty( 'nextUrl.pathname', '/'