Files
arad-arisman/src/middleware.ts
T
Alireza HassaniandCursor fc4fea89f1 Fix production 500 caused by conflicting dynamic product/blog routes.
Remove legacy [slug] pages that clashed with [id]/[slug] and handle old URLs via middleware redirects instead.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 23:49:10 +03:30

70 lines
2.4 KiB
TypeScript

import { NextResponse, type NextRequest } from "next/server";
import { slugifyFa } from "@/lib/slugify";
import { TENANT_DOMAIN } from "@/lib/meshkee";
const API_BASE = "https://api.meshkee.com/api/v1";
function canonicalProductPath(product: { id: string; nameFa: string }) {
return `/products/${product.id}/${encodeURIComponent(slugifyFa(product.nameFa))}`;
}
function canonicalBlogPath(post: { id: string; nameFa?: string; titleFa?: string; title?: string }) {
const title = post.nameFa || post.titleFa || post.title || "post";
return `/blog/${post.id}/${encodeURIComponent(slugifyFa(title))}`;
}
async function redirectLegacyProduct(slug: string, request: NextRequest) {
const res = await fetch(
`${API_BASE}/tenants/${TENANT_DOMAIN}/products/${encodeURIComponent(slug)}`,
{ next: { revalidate: 300 } },
);
if (!res.ok) return null;
const data = (await res.json()) as { product?: { id: string; nameFa: string } };
const product = data.product;
if (!product) return null;
return NextResponse.redirect(new URL(canonicalProductPath(product), request.url), 308);
}
async function redirectLegacyBlog(slug: string, request: NextRequest) {
const res = await fetch(
`${API_BASE}/tenants/${TENANT_DOMAIN}/blogs/${encodeURIComponent(slug)}`,
{ next: { revalidate: 300 } },
);
if (!res.ok) return null;
const data = (await res.json()) as {
blog?: { id: string; nameFa?: string; titleFa?: string; title?: string };
post?: { id: string; nameFa?: string; titleFa?: string; title?: string };
};
const post = data.blog ?? data.post;
if (!post) return null;
return NextResponse.redirect(new URL(canonicalBlogPath(post), request.url), 308);
}
export async function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
const productMatch = pathname.match(/^\/products\/([^/]+)$/);
if (productMatch) {
const segment = decodeURIComponent(productMatch[1]);
if (segment !== "category" && !/^\d+$/.test(segment)) {
const redirect = await redirectLegacyProduct(segment, request);
if (redirect) return redirect;
}
}
const blogMatch = pathname.match(/^\/blog\/([^/]+)$/);
if (blogMatch) {
const segment = decodeURIComponent(blogMatch[1]);
if (!/^\d+$/.test(segment)) {
const redirect = await redirectLegacyBlog(segment, request);
if (redirect) return redirect;
}
}
return NextResponse.next();
}
export const config = {
matcher: ["/products/:path*", "/blog/:path*"],
};