404s on the first access to the homepage

I get a 404 error every time I make the first request to my app homepage. It will work after a simple refresh.

Steps to reproduce:
Access https://www.zaptube.vip or curl -I https://www.zaptube.vip

curl -I https://www.zaptube.vip
HTTP/2 404 
accept-ranges: bytes
access-control-allow-origin: *
age: 119
cache-control: public, max-age=0, must-revalidate
content-disposition: inline; filename="404"
content-type: text/html; charset=utf-8
date: Wed, 08 Jan 2025 14:09:49 GMT
etag: "d3503f134747dd752bf9b78f170299cb"
last-modified: Wed, 08 Jan 2025 14:07:50 GMT
server: Vercel
set-cookie: locale=en; Path=/
strict-transport-security: max-age=63072000
x-matched-path: /404
x-vercel-cache: HIT
x-vercel-id: gru1::fjlft-1736345389516-af4b261091a4
content-length: 5939

In the logs I see the 404s related to requests to the /wordpress/wp-admin/setup-config.php and /wp-admin/setup-config.php endpoints (I’m not sure what are those)

I’ve tried some workarounds without success :confused:
This is the [locale]/[slug] page:

import { redirect } from "next/navigation";
import { ChannelService } from "@/app/services/channel.service";
import SubscribePage from "@/app/[locale]/subscribe/[slug]/page";

export default async function ChannelPage({
  params,
}: {
  params: { slug: string };
}) {
  const channelService = new ChannelService();
  let decodedSlug = decodeURIComponent(params.slug);

 if (decodedSlug.includes("wp-admin") || decodedSlug.includes("setup-config.php")) {
    console.warn(`[ChannelPage] Invalid slug: ${decodedSlug}`);
    return redirect("/");
  }

  // all slugs should start with @ in the db, we will allow the user to not include it in the url
  if (!decodedSlug.startsWith("@")) {
    decodedSlug = `@${decodedSlug}`;
  }

  const channel = await channelService.getChannel({ slug: decodedSlug }, {});

  if (!channel) {
    console.warn(`[ChannelPage] Channel not found: ${decodedSlug}`);
    return redirect("/");
  }

  if (channel?.defaultLocale) {
    redirect(`/${channel.defaultLocale}/subscribe/${decodedSlug}`);
  }

  return <SubscribePage params={{ slug: decodedSlug }} />;
}

This is how my middleware is configured:

import createMiddleware from "next-intl/middleware";
import { NextRequest, NextResponse } from "next/server";
import { withAuth } from "next-auth/middleware";
import { locales, defaultLocale } from "@/app/i18n/settings";

const intlMiddleware = createMiddleware({
  locales,
  defaultLocale,
  localePrefix: "never", // Prevent locales in the URL
});

const authMiddleware = withAuth(
  function middleware(req) {
    if (
      req.nextUrl.pathname.startsWith("/admin") &&
      req.nextauth.token === null
    ) {
      return NextResponse.redirect(
        new URL(`/login?callbackUrl=${encodeURIComponent(req.url)}`, req.url)
      );
    }
    return NextResponse.next(); // Proceed if authenticated
  },
  {
    callbacks: {
      authorized: ({ token }) => !!token,
    },
  }
);

export default function middleware(request: NextRequest) {
  const pathname = request.nextUrl.pathname;

  console.log(`[Middleware] Requested path: ${pathname}`);

  // Block invalid paths early
  const blockedPatterns = ["wp-admin", "setup-config.php"];
  if (blockedPatterns.some((pattern) => pathname.includes(pattern))) {
    console.warn(`[Middleware] Blocked invalid path: ${pathname}`);

    // Initialize `next-intl` before redirecting
    intlMiddleware(request);
    return NextResponse.redirect(new URL("/", request.url));
  }

  const localeCookie = request.cookies.get("locale");

  // Admin route logic
  if (pathname.startsWith("/admin")) {
    const response = authMiddleware(request as any, {} as any);

    if (!localeCookie) {
      const preferredLocale =
        request.headers.get("accept-language")?.split(",")[0].split("-")[0] ||
        defaultLocale;

      if (response instanceof NextResponse) {
        response.cookies.set("locale", preferredLocale, { path: "/" });
        return response;
      }
    }

    return intlMiddleware(request);
  }

  // Set locale cookie if not already set
  if (!localeCookie) {
    const preferredLocale =
      request.headers.get("accept-language")?.split(",")[0].split("-")[0] ||
      defaultLocale;

    const response = NextResponse.next();
    response.cookies.set("locale", preferredLocale, { path: "/" });
    return response;
  }

  // Ensure intlMiddleware runs for all other requests
  return intlMiddleware(request);
}

export const config = {
  matcher: ["/((?!api|_next).*)"],
  methods: ["GET", "HEAD"],
};

There’s another community post with 404 debugging tips that might be helpful. Please give these solutions a try and let us know how it goes.

A human should be around soon to offer more advice. But you can also get helpful information quickly by asking v0.

It seems the issue was that I was calling createMiddleware from import createMiddleware from "next-intl/middleware"; before setting the locale value + some issues with the default config on the GoDaddy DNS (I’ve now moved to the Vercel DNS).

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.