Next.js Discord

Discord Forum

Dynamic axios language with Nextjs

Unanswered
West African Lion posted this in #help-forum
Open in Discord
West African LionOP
import axios, { InternalAxiosRequestConfig } from 'axios';
import { API_URL } from '../config/app';
import { getSession } from 'next-auth/react';

const instance = axios.create({
baseURL: API_URL,
proxy: false,
headers: {
'Content-Type': 'application/json',
},
});

instance.interceptors.request.use(
async (config: InternalAxiosRequestConfig) => {
const session = await getSession();

config.baseURL = ${API_URL}/en-GB;

if (session?.user.token) {
config.headers.Authorization = Bearer ${session.user.token};
}
return config;
},
(error) => {
console.log(error);
return Promise.reject(error);
}
);

export default instance;

I am using axios for my nextjs app for making requests. I want the en-GB to be dynamic. How could I call the locale using next-intl ?

113 Replies

Toyger
you basically have valid example already, you can get language from session and put it in baseURL like you are doing with authorization header, just set it in session callback earlier, and then apply there
you can get locale from router
const router = useRouter()
const currentLang =  router.locale
West African LionOP
hooks can not be called inside that code.
from where are you importing useRouter?
Toyger
import { useRouter } from 'next/router'


hooks can not be called inside that code.
hmm ok, you can call it in some shared component, probably even layout, and then save it somewhere maybe even in localstorage, and you can ignore session then completely.
Korat
@Ray using useLocale blocks all requests, i ended up with a network like soo
it needed to be use on server side because useLocale use headers() under the hood
Korat
@Ray Ah i get it, we use it in the client
Korat
Is there any possible way to call it in client?
@Korat Is there any possible way to call it in client?
yes with the package eg, zustand, preact/signal or nanostore
const instance = axios.create({
  baseURL: API_URL,
  proxy: false,
  headers: {
    "Content-Type": "application/json",
  },
});

instance.interceptors.request.use(
  async (config: InternalAxiosRequestConfig) => {
    const session = await getSession();
    const locale = typeof window === 'undefined' ? useLocale() : useLocaleStore.getState().locale;
    config.baseURL = `${API_URL}/${locale}`;

    if (session?.user.token) {
      config.headers.Authorization = `Bearer ${session.user.token}`;
    }
    return config;
  },
  (error) => {
    console.log(error);
    return Promise.reject(error);
  }
);

// local-store.ts
const useLocaleStore = create((set) => ({
  locale: "",
  setLocale: (locale) => set({ locale }),
}));

// locale.tsx
"use client";

import { usePathname } from "../navigation";

function Locale() {
  // When the user is on `/en`, this will be `/`
  const pathname = usePathname();
  const setLocale = useLocaleStore((state) => state.setLocale);
  useEffect(() => {
    setLocale(pathname.split("/").at(1));
  }, [pathname]);

  return <></>
}

// [locale]/layout.tsx
export default function Layout({ children }) {
  return (
    <>
      <Locale />
      {children}
    </>
  );
}

something like this
Korat
I will give it a shot a bit later thank you so much 🙌
Korat
Hmm, i dont understand why calling anything in axios instance crashes the app
const locale = useLocaleStore().getState().locale;
const locale = useStore(useLocaleStore).locale;
the syntax of the first is not correct, i changed it to the second one
and my app goes blank
Korat
@Ray just calling console.log(window) is crashing the app
no you need useLocaleStore().getState().locale
useLocaleStore.getState().locale maybe
Korat
Im starting to think maybe axios is not even being called in client
console.log(window) crashes the app
@Ray useLocaleStore.getState().locale maybe
Korat
this worked but its returnign empty string
which mean you didn't set it
Korat
im, the useeffect is being triggered
the axios interceptors only run once when the instance is created?
Korat
interceptors run whenever a request is being sent
I think the issue is with axios being ran in server side, and i dont even know why
becuase i get both logs in client console and in server terminal
weirdly
because client component will be run on server first
clientInstance.interceptors.request.use(
  async (config: InternalAxiosRequestConfig) => {
    const session = await getSession();
    const locale = typeof window === 'undefined' ? useLocale() : useLocaleStore.getState().locale;
    config.baseURL = `${API_URL}/${locale}`;

    if (session?.user.token) {
      config.headers.Authorization = `Bearer ${session.user.token}`;
    }
    return config;
  },
  (error) => {
    console.log(error);
    return Promise.reject(error);
  }
);
try this maybe
Korat
we are getting somewhere, now the client returns empty, the server returns en
yet it crashes the app with some errors
btw where are you taking useLocale from ?
next-intl
Korat
useEffect(() => {
setLocale(pathname.split('/').at(0) || 'whattt');
}, [pathname]);

this is not setting the locale correctly, its taking the latter
yea my code isn't tested lol
Korat
thats what im doing, and im also trying to understand why
nextjs is some woddo thing hahahahha i swear
Korat
Yes i think its working
Korat
I think i fixed it by doing those changes now
const languages: Record<string, string> = {
  '/': 'en-GB',
  '/fr': 'fr-FR',
};

instance.interceptors.request.use(
  async (config: InternalAxiosRequestConfig) => {
    const session = await getSession();
    const locale =
      typeof window === 'undefined'
        ? 'en-GB'
        : languages[useLocaleStore.getState().locale];

    config.baseURL = `${API_URL}/${locale}`;

    if (session?.user.token)
      config.headers.Authorization = `Bearer ${session.user.token}`;

    return config;
  },
  (error) => {
    console.log(error);
    return Promise.reject(error);
  }
);
one thing that is worrying me now is that when being executed on server (typeof window === 'undefined'), it crashed the app, so my question is, should it execute the query in server right ?
does next work like that ?
one request from server and one request from client
that's why i changed it to ? 'en-GB'
as a default
const locale = languages[useLocaleStore.getState().locale || 'en-GB'];
Korat
yeah this crashes the app
what error?
Korat
 const locale =
      typeof window === 'undefined'
        ? 'en-GB'
        : languages[useLocaleStore.getState().locale];

this work right?
@Ray ts const locale = typeof window === 'undefined' ? 'en-GB' : languages[useLocaleStore.getState().locale]; this work right?
if this works, then this should also work
const locale = typeof window === 'undefined' ? useLocale() : useLocaleStore.getState().locale;
Korat
this one is crashing the app, my god this is soo confusing
my version works
but it shows this in the network
i've probably fucked up somewhere
maybe a misconfig with axios and next 13
useLocale is a hook right ?
@Korat i've probably fucked up somewhere
how about this?
let locale
if (typeof window === 'undefined') {
    locale = useLocale()
} else {
    locale =  useLocaleStore.getState().locale
}
Korat
nope
useLocale is crashing the app
thats a hook and i believe it can't be used in interceptors
Korat
lemme try to update the package
im at ^3.0.0-beta.14
maybe its taking the client version
or try
import { getLocale } from "next-intl/server";
Korat
Huh, i think i finally got it working, upgraded next-intl, upgraded nextjs, imma have to see if i have fully solved the issue or not
thanks for the help tho man, your the goat
Korat
Im wondering why Link from next/link doesnt redirect to /lang/whatever
it skips the lang
@Korat it skips the lang
use Link from them?
Korat
next-intl i was using the lastest beta version before they went to a stable version and for next js i was using version 13.something
Oh, okay bro but then why should we need next/link ?
its obsolete right ?
they wrap the next/link with the current locale i think
Korat
Most likely
Im feeling betta now hahaha, 24 changes
are you using useLocale or getLocale?
Korat
now im using useLocale in axios config
so the problem was the version of next-intl?
Korat
Yeah, I had to build it from start with the new documentation
ah ok
Korat
Before closing, is nextjs sending two requests to my backend, because i can see both my server console and client console printing the value in axios interceptor
are you prefetching query?
on server
Korat
Im using useQuery
no i dont think soo
try setting refetchOnMount to false on queryClient
should be refetchOnMount
Korat
Nah still the same, but showing the log in the server terminal doesnt necessary mean that its requesting or api right
i might have to check it in depth with the backend guys
our*
what log?
Korat
whatever i log in axios interceptor
oh then it doesn't mean it fetch twice
Korat
se what i mean
the page render on server and a axios instance is created, then the page get hydrated on client and another axios instance is created
Korat
Ohh that makes sense, man i wish i had a senior like you at my work
thanks a lot for the explanation