NextJS 13: How to pass data from middleware to components?
Asked Answered
T

2

7

in NextJS 13 with app folder, I need to get data based on url (language from e.g. /en/asdf/ or /de/asdf/) and pass it to components.
I tried using middleware and it seemed to work relatively well using cookies, but there is one big problem - the cookie is only available in the components after the next reload, not immediately.
Is there any way to pass data from middleware to components?
Or something else, like some Global variables?

Shortcode of my middleware:

import { NextResponse } from 'next/server'

export const middleware = (req) => {
    const pathname = req.nextUrl.pathname
    const language = pathname.split('/')[1]
    const allowedLanguages = ['en', 'de'];

    if(allowedLanguages.includes(language)) {
        const response = NextResponse.rewrite(new URL(pathname.replace(`/${language}`, ''), req.url))
        
        // This works only after browser reload
        response.cookies.set('language', language)

        return response
    }
}

export const config = {
    matcher: ['/((?!assets|api|_next/static|favicon.ico).*)'],
}


Thanks

Thinner answered 10/12, 2022 at 22:15 Comment(2)
you make a request to an api route, and middleware sits between, it takes your request, you can apply some logic to request if request passes, it will hit the api route, and isnide api route you send response to the clientDispersion
@Dispersion Thank you, but I'm not sure what you mean. Could you please give a specific example?Thinner
D
0

Like @Yilmaz mentioned You can make an api route /api/dict/language/route.js

import { cookies } from "next/headers";
import { NextResponse } from "next/server";

export async function GET() {
  const cookieStore = cookies();

  const token = cookieStore.get("language")?.value;
  if (!token) {
    return NextResponse.json(
      {
        message: "Unauthorized",
      },
      {
        status: 401,
      }
    );
  }
  return NextResponse.json(token, {
    status: 200,
  });
}

and then fetch the data

const { data } = await axios.get("/api/dict/language");
Demmer answered 8/7, 2023 at 2:23 Comment(0)
C
0

Although this is not a method using middleware, it can be implemented similarly using nextjs' dynamic routes.

If you create a folder in the [...slug] format within the app folder, you can use the path parameters in page.tsx.

// /app/[...slug]/page.tsx
import ClientComponent from "@/components/ClientComponent";

export default function Page({ params }: { params: { slug: string[] } }) {
  const { slug } = params;
  return <ClientComponent slug={slug} />;
}

When accessing /en/asdf/, the slug becomes ['en', 'asdf'], and this can be passed to the client component.

Carl answered 29/11, 2023 at 6:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.