Advanced Next.js middleware patterns for authentication, routing, and request modification at the edge.
# Edge Middleware Routing Patterns for Google Antigravity
Next.js Middleware runs at the edge before requests reach your application, enabling powerful authentication, routing, and request modification patterns. Google Antigravity's Gemini 3 helps you implement sophisticated middleware logic with intelligent suggestions.
## Middleware Configuration
Create a comprehensive middleware setup with matcher configuration:
```typescript
// middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
const token = request.cookies.get("auth-token")?.value;
const isAuthenticated = !!token;
const publicRoutes = ["/", "/login", "/signup", "/about"];
const authRoutes = ["/login", "/signup", "/forgot-password"];
const protectedRoutes = ["/dashboard", "/settings", "/profile"];
const adminRoutes = ["/admin"];
const isPublicRoute = publicRoutes.includes(pathname);
const isAuthRoute = authRoutes.includes(pathname);
const isProtectedRoute = protectedRoutes.some(route =>
pathname.startsWith(route)
);
const isAdminRoute = adminRoutes.some(route =>
pathname.startsWith(route)
);
if (isAuthRoute && isAuthenticated) {
return NextResponse.redirect(new URL("/dashboard", request.url));
}
if (isProtectedRoute && !isAuthenticated) {
const loginUrl = new URL("/login", request.url);
loginUrl.searchParams.set("callbackUrl", pathname);
return NextResponse.redirect(loginUrl);
}
if (isAdminRoute) {
if (!isAuthenticated) {
return NextResponse.redirect(new URL("/login", request.url));
}
const userRole = request.cookies.get("user-role")?.value;
if (userRole !== "admin") {
return NextResponse.redirect(new URL("/unauthorized", request.url));
}
}
return NextResponse.next();
}
export const config = {
matcher: [
"/((?!api|_next/static|_next/image|favicon.ico|public).*)",
],
};
```
## Geolocation-Based Routing
Implement location-aware routing using edge geolocation:
```typescript
// middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
const COUNTRY_REDIRECTS: Record<string, string> = {
DE: "/de",
FR: "/fr",
ES: "/es",
JP: "/ja",
};
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
const country = request.geo?.country || "US";
const localePrefixes = Object.values(COUNTRY_REDIRECTS);
const hasLocalePrefix = localePrefixes.some(prefix =>
pathname.startsWith(prefix)
);
if (hasLocalePrefix) {
return NextResponse.next();
}
const redirectPath = COUNTRY_REDIRECTS[country];
if (redirectPath && pathname === "/") {
const preferredLocale = request.cookies.get("preferred-locale")?.value;
if (!preferredLocale) {
const response = NextResponse.redirect(
new URL(redirectPath, request.url)
);
response.cookies.set("detected-country", country);
return response;
}
}
return NextResponse.next();
}
```
## Rate Limiting at Edge
Implement basic rate limiting using edge KV storage:
```typescript
// middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
const RATE_LIMIT = 100;
const WINDOW_SIZE = 60 * 1000;
const requestCounts = new Map<string, { count: number; resetTime: number }>();
function getRateLimitKey(request: NextRequest): string {
const forwarded = request.headers.get("x-forwarded-for");
const ip = forwarded?.split(",")[0] || "anonymous";
return `rate-limit:${ip}`;
}
export function middleware(request: NextRequest) {
if (!request.nextUrl.pathname.startsWith("/api")) {
return NextResponse.next();
}
const key = getRateLimitKey(request);
const now = Date.now();
const record = requestCounts.get(key);
if (!record || now > record.resetTime) {
requestCounts.set(key, { count: 1, resetTime: now + WINDOW_SIZE });
return NextResponse.next();
}
if (record.count >= RATE_LIMIT) {
return new NextResponse(
JSON.stringify({ error: "Too many requests" }),
{
status: 429,
headers: {
"Content-Type": "application/json",
"Retry-After": String(Math.ceil((record.resetTime - now) / 1000)),
"X-RateLimit-Limit": String(RATE_LIMIT),
"X-RateLimit-Remaining": "0",
},
}
);
}
record.count++;
const response = NextResponse.next();
response.headers.set("X-RateLimit-Remaining", String(RATE_LIMIT - record.count));
return response;
}
```
## Request/Response Headers
Modify headers for security and tracking:
```typescript
// middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
const requestId = crypto.randomUUID();
const requestHeaders = new Headers(request.headers);
requestHeaders.set("x-request-id", requestId);
const response = NextResponse.next({
request: { headers: requestHeaders },
});
response.headers.set("X-Request-ID", requestId);
response.headers.set("X-Frame-Options", "DENY");
response.headers.set("X-Content-Type-Options", "nosniff");
return response;
}
```
## Best Practices
1. **Keep middleware lightweight** - Heavy computation delays all requests
2. **Use matcher config** - Exclude static assets from middleware
3. **Cache authorization decisions** - Reduce token validation overhead
4. **Handle errors gracefully** - Return appropriate status codes
5. **Log important events** - Track authentication failures and rate limits
Edge middleware with Google Antigravity enables powerful request interception with intelligent pattern suggestions and security best practices.This middleware prompt is ideal for developers working on:
By using this prompt, you can save hours of manual coding and ensure best practices are followed from the start. It's particularly valuable for teams looking to maintain consistency across their middleware implementations.
Yes! All prompts on Antigravity AI Directory are free to use for both personal and commercial projects. No attribution required, though it's always appreciated.
This prompt works excellently with Claude, ChatGPT, Cursor, GitHub Copilot, and other modern AI coding assistants. For best results, use models with large context windows.
You can modify the prompt by adding specific requirements, constraints, or preferences. For middleware projects, consider mentioning your framework version, coding style, and any specific libraries you're using.