Next.js rewrites + custom dynamical header for axios on the server-side

618 views Asked by At

How i can do dynamical header for axios on the serve-side? I want to make functionality of cities, without edit nextjs folder structure. Rewrities from nextjs solves my problem, but I can't set the header for axios request functions on the server side. useRouter() hook returns non-proxied path.

// next.config.js

...
async Rewrites() {
  return [
    {
      source: '/new-york/:path*',
      destination: '/:path*',
    },
  ]
}
...

Im tried use axios intreception function:

// destination _app.js

export default function AxiosInterceptors() {
...
    const router = useRouter();
    const asPath = router.asPath; // asPath return not non-proxied path, if i use url /new-york/blogs, here i see /blogs;

    apiQr.interceptors.request.use(function (config) {
        config.headers['city'] = asPath.includes('/new-york') ? '2' : '1'; // city id
        return config;
    }, function (error) {
        return Promise.reject(error);
    });
...

}

Im also tried set headers from NextJS _middleware.js but there is no access to axios requests and the axios interceptor function is not called there. Where and how can I get a stable variable depending on the entered url on the server side so that I can adjust the axios headers?

I expect to get the proxied url in the axios interceptors instance as I showed above, but I get the proxied path.

1

There are 1 answers

0
Natalia Markoborodova On

I'm not sure what exactly you mean by "there is no access to axios request" in the middleware, but here is what worked for me:

// middleware.ts
export async function middleware(req: NextRequest) {
  const {pathname, host, protocol, port} = req.nextUrl;
  if (pathname.startsWith("/some/url")) 
    // here you can access some headers from your axios request 
    const user = req.headers.get('x-username')
    // ... some logic depending on what headers you set in your original request
       
    const rewriteUrl = req.nextUrl.clone();
    const url = new URL("https://another.host/some/url");
    
    rewriteUrl.host = url.host
    rewriteUrl.protocol = url.protocol;
    rewriteUrl.port = url.port;

    const newHeaders = new Headers(req.headers)

    // I needed to delete the old headers:
    newHeaders.forEach((_, headerName) => {
      req.headers.delete(headerName);
    });

    // And here we can set the new ones:
    newHeaders.set("Authorization", "forExampleBasicuthBase64HashForAnotherHost")
    newHeaders.set("Content-Type", "application/json; charset=utf-8")

    const response = NextResponse.rewrite(rewriteUrl, {
      request: {
        headers: newHeaders,
      },
    })

    return response
}

And you can pass the custom headers like variables when sending your axios request like that:

axios({
    method: "post",
    url: "/some/url",

    ....

    headers: {
        'x-username': someUserNameOrAnotherVariable,
    },
        
    }).catch(function (error) {
        ...
    })

Here is the documentation.

Hope it helps!