Reputation: 911
In some of my pages I'm using getServerSideProps
to make API calls and redirect the user if necessary. The web APP I'm building is multilingual and I need to always show the user the correct language.
The homepage /
uses getServerSideProps
and redirects the user either to the profile or the login page. For that I do the following:
return {
redirect: {
permanent: false,
destination: someLogic ? `${context.locale}/login` : `${context.locale}/profile`,
},
};
now the profile and user pages use getServerSideProps
too, to check if there's a valid session and redirect the user if necessary. For instance the user will try access the profile page when he's session is expired, he will then be redirected to the login page. if I set the destination
property to /login
the locale property will be overriden and the user will get the default language and be redirected to domain/login
. If I set it to ${context.locale}/login
and the page that was originally called is domain/fr-FR/profile
then the user will be redirected to domain/fr-FR/fr-FR/login
Client side redirecting with router.push
or router.replace
is working fine and returning the correct urls.
To my understanding I can't get the absolute URL from the context of the getServerSideProps
to check if the locale is already set, how can I then solve this problem?
I'm currently using next 10.0.4
and this is my next.config.js
:
module.exports = {
i18n: {
locales: ['de-DE', 'en-US', 'fr-FR', 'nl-NL', 'it-IT'],
defaultLocale: 'en-US',
localDetection: true,
}
}
Upvotes: 6
Views: 10172
Reputation: 50278
The locale is being applied twice because you're setting the destination path without a leading /
. Simply adding a /
at the beginning should fix your issue.
return {
redirect: {
permanent: false,
destination: someLogic ? `/${context.locale}/login` : `/${context.locale}/profile`
// ^ ^
}
};
Upvotes: 0
Reputation: 499
I had the same issue and solved it following the next steps:
export const getServerSideProps = async (context) => {
const { locale } = context;
return {
redirect: {
destination: `/${locale}${getLoginPageUrl()}`,
permanent: false,
},
};
Here is the whole code of my guard:
export function withAuthServerSideProps(getServerSidePropsFunc) {
return async (context) => {
const {
req: { cookies },
query: { city },
locale,
} = context;
if (!cookies.userToken) {
return {
redirect: {
destination: `/${locale}${getLoginPageUrl(city ? city : '')}`,
permanent: false,
},
};
}
if (getServerSidePropsFunc) {
return { props: { data: await getServerSidePropsFunc(context) } };
}
return { props: {} };
};
}
And here is an example of how I use it:
export const getServerSideProps = withAuthServerSideProps(async (context) => {
const res = await ProductsService.fetchOrderDetails({
id: 'b324015f-bf3f-4862-9817-61b954278168',
});
if (!res.data) {
return {
notFound: true,
};
}
return {
props: {
orderDetails: res.data,
},
};
});
Please keep in mind that if you use this guard your props will be in data, so for example in order for me to access the orderDetails from the previous code in my page I have to make the following:
const OrderConfirmed = ({ data }) => (
<OrderConfirmedPageWrapper orderDetails={data?.props?.orderDetails} />
);
I'm currently using "next": "10.0.6"
, here is my next.config.js
:
i18n: {
locales: [
'en-kw',
'ar-kw',
'en-sa',
'ar-sa',
'en-qa',
'ar-qa',
'en-bh',
'ar-bh',
'en-ae',
'ar-ae',
'en-gb',
'ar-gb',
'catchAll',
],
defaultLocale: 'catchAll',
},
Upvotes: 3