Redirect from client component
Unanswered
Harlequin posted this in #help-forum
HarlequinOP
Hey guys. I have a single page where I'm fetching data and passing it to client component with react-hook-form etc. On form submit I'm calling server action which works perfectly fine. After successful submission I'm trying to have a redirect to confirmation page. I'm just using router.push("/confirmation"). Url is changing but after it I'm getting Error: async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding
it's a simple page with some text and that's it. File structure is under /app/[lng] because I'm using i18next. When I tried to just use route.push() in button for example it's totally fine.
'use client' to a module that was originally written for the server. I'm just thinking what can be wrong on this page: import { useTranslation } from "@app/i18n";
import { Params } from "@app/types";
import { Box, Typography } from "@mui/material";
import Grid from "@mui/material/Grid";
export default async function Confirmation({ params: { lng } }: Params<{ lng: string }>) {
const { t } = await useTranslation(lng);
return (
<Box sx={{ margin: "0 auto", maxWidth: "900px" }}>
<Grid container spacing={2} justifyContent="center">
<Grid item xs={12}>
<Typography color="primary.main" align="center" fontSize={24} component={"h1"}>
{t(`Confirmation.Title`)}
</Typography>
</Grid>
</Grid>
</Box>
);
}it's a simple page with some text and that's it. File structure is under /app/[lng] because I'm using i18next. When I tried to just use route.push() in button for example it's totally fine.
40 Replies
HarlequinOP
bump
I think you should use
redirect() in the server action instead of redirection in the client sideHarlequinOP
Yeah I tried it but totally no effect
or sometimes throwing the same
I tried with redirect and permamentRedirect
sometimes it cause same issue and sometimes it's not doing anything - just some requests in network tab and that's it
no actual redirect
"wav-grant" is my server action
and why confirmation is getting this rsc param?
HarlequinOP
I tried with permanentRedirect again and I see that's adding status for my server action
and next request is page.js
but it remains on same page still
do you have redirect inside try catch?
HarlequinOP
no no, like in documentation I have try catch and after it I have redirect
I even added revalidatePath because I found something like that and still the same
I was thinking that the problem is in middleware because I have i18next, so it paths have this [lng]
@Harlequin I even added revalidatePath because I found something like that and still the same
nope, revalidatePath is not related to the redirection, it's just purging the cache
HarlequinOP
but even after using exact url "/en/confirmation"
it's better to share the code @Harlequin
HarlequinOP
it's still the same
okay give me a sec
page.tsx for view with form
import { Heading } from "@app/[lng]/components/UI/heading/heading";
import { getGrantLimits, getVehicleAgeDictionary } from "@app/actions/common";
import { MAIN_FORMS_TRANSLATION_KEYS, useTranslation } from "@app/i18n";
import { GrantType, Params } from "@app/types";
import { Container, Link, Typography } from "@mui/material";
import { Trans } from "react-i18next/TransWithoutContext";
import { WavGrantForm } from "./wav-grant-form";
const { WAV_GRANT_FORM } = MAIN_FORMS_TRANSLATION_KEYS;
export default async function WavGrant({ params: { lng } }: Params<{ lng: string }>) {
const { t } = await useTranslation(lng);
const proposedVehicleAge = await getVehicleAgeDictionary();
const grantLimits = await getGrantLimits();
const isWavOpen = grantLimits.includes(GrantType.Keys.WAVGrant as never);
const currentYear = new Date().getFullYear();
return (
<Container>
<WavGrantForm
proposedVehicleAge={proposedVehicleAge.filter((age) => age.grantType === GrantType.Keys.WAVGrant)}
currentYear={currentYear}
/>
);
}these two request are fetching some dictionaries
btw sometimes I'm getting in console "grantLimits.includes is not a function" but it loads normally
here is a part in Client component WavGrantForm
const onSubmit: SubmitHandler<Grant.FormStateFields> = async (data) => {
if (!executeRecaptcha) {
console.error(RECAPTCHA_MESSAGES.CLIENT_FAILED);
return;
}
executeRecaptcha(FORM_NAMES.WAV_GRANT)
.then(async (recaptchaToken: string) => {
const { attachments } = data.caseGrantRequestDetails;
let fileInfo: FileInfo[] = [];
if (attachments && attachments?.length) {
const { data: uploadFileResponseData } = await fileUpload(attachments || []);
fileInfo = Object.keys(uploadFileResponseData).length ? uploadFileResponseData : [];
}
const result = await createGrantCase({
...data,
caseGrantRequestDetails: { ...data.caseGrantRequestDetails, attachments: fileInfo },
grantType: GrantType.Keys.WAVGrant,
recaptchaToken
});
if (isError(result)) {
toast(result.error, { type: "error" });
} else {
toast(result, { type: "success" });
// router.refresh();
// router.push("/confirmation");
}
})
.catch((err) => toast(err));
};normal react-hook-form submit
with recaptcha
uploading files etc
some other things, adjustment, then final request to my .net api
and permanent redirect at the end
and the page.tsx where this redirect should go
import { useTranslation } from "@app/i18n";
import { Params } from "@app/types";
import { Box, Typography } from "@mui/material";
import Grid from "@mui/material/Grid";
export default async function Confirmation({ params: { lng } }: Params<{ lng: string }>) {
const { t } = await useTranslation(lng);
return (
<Box sx={{ margin: "0 auto", maxWidth: "900px" }}>
<Grid container spacing={2} justifyContent="center">
<Grid item xs={12}>
<Typography color="primary.main" align="center" fontSize={24} component={"h1"}>
{t(`Confirmation.Title`)}
</Typography>
</Grid>
</Grid>
</Box>
);
}nothing special
HarlequinOP
is the formatting is fine? discord paste it as it wants 😄
HarlequinOP
@James4u