Support for urls with searchparams when using server actions

This commit is contained in:
DrMint 2024-07-11 23:00:56 +02:00
parent a0e7d97967
commit e7eb324cb1
4 changed files with 69 additions and 47 deletions

View File

@ -16,6 +16,13 @@ interface Props {
const { withTitle, ...otherProps } = Astro.props; const { withTitle, ...otherProps } = Astro.props;
const { t } = await getI18n(Astro.locals.currentLocale); const { t } = await getI18n(Astro.locals.currentLocale);
const getActionCurrency = (value: string) => {
const requestSearchParams = new URL(Astro.request.url).searchParams;
const newSearchParams = new URLSearchParams(requestSearchParams);
newSearchParams.set("action-currency", value);
return `?${newSearchParams}`;
};
--- ---
{/* ------------------------------------------- HTML ------------------------------------------- */} {/* ------------------------------------------- HTML ------------------------------------------- */}
@ -29,7 +36,7 @@ const { t } = await getI18n(Astro.locals.currentLocale);
"pressable-link", "pressable-link",
prepareClassForSelectedCurrencyPostProcessing({ currency: id }), prepareClassForSelectedCurrencyPostProcessing({ currency: id }),
]} ]}
href={`?action-currency=${id}`}> href={getActionCurrency(id)}>
{`${id} (${formatCurrency(id)})`} {`${id} (${formatCurrency(id)})`}
</a> </a>
)) ))

View File

@ -14,6 +14,13 @@ const { withTitle, ...otherProps } = Astro.props;
const { currentLocale } = Astro.locals; const { currentLocale } = Astro.locals;
const { t } = await getI18n(currentLocale); const { t } = await getI18n(currentLocale);
const getActionLanguage = (value: string) => {
const requestSearchParams = new URL(Astro.request.url).searchParams;
const newSearchParams = new URLSearchParams(requestSearchParams);
newSearchParams.set("action-lang", value);
return `?${newSearchParams}`;
};
--- ---
{/* ------------------------------------------- HTML ------------------------------------------- */} {/* ------------------------------------------- HTML ------------------------------------------- */}
@ -24,7 +31,7 @@ const { t } = await getI18n(currentLocale);
contextCache.locales.map((locale) => ( contextCache.locales.map((locale) => (
<a <a
class:list={{ current: currentLocale === locale, "pressable-link": true }} class:list={{ current: currentLocale === locale, "pressable-link": true }}
href={`?action-lang=${locale}`}> href={getActionLanguage(locale)}>
{formatLocale(locale)} {formatLocale(locale)}
</a> </a>
)) ))

View File

@ -5,19 +5,26 @@ import { getI18n } from "src/i18n/i18n";
const { currentLocale } = Astro.locals; const { currentLocale } = Astro.locals;
const { t } = await getI18n(currentLocale); const { t } = await getI18n(currentLocale);
const getActionThemeUrl = (value: "dark" | "light" | "auto") => {
const requestSearchParams = new URL(Astro.request.url).searchParams;
const newSearchParams = new URLSearchParams(requestSearchParams);
newSearchParams.set("action-theme", value);
return `?${newSearchParams}`;
};
--- ---
{/* ------------------------------------------- HTML ------------------------------------------- */} {/* ------------------------------------------- HTML ------------------------------------------- */}
<Tooltip trigger="click"> <Tooltip trigger="click">
<div id="content" slot="tooltip-content"> <div id="content" slot="tooltip-content">
<a class="pressable-link underline-when-dark" href="?action-theme=dark"> <a class="pressable-link underline-when-dark" href={getActionThemeUrl("dark")}>
{t("global.theme.dark")} {t("global.theme.dark")}
</a> </a>
<a class="pressable-link underline-when-auto" href="?action-theme=auto"> <a class="pressable-link underline-when-auto" href={getActionThemeUrl("auto")}>
{t("global.theme.auto")} {t("global.theme.auto")}
</a> </a>
<a class="pressable-link underline-when-light" href="?action-theme=light"> <a class="pressable-link underline-when-light" href={getActionThemeUrl("light")}>
{t("global.theme.light")} {t("global.theme.light")}
</a> </a>
</div> </div>

View File

@ -12,25 +12,25 @@ import { trackEvent } from "src/shared/analytics/analytics";
const ninetyDaysInSeconds = 60 * 60 * 24 * 90; const ninetyDaysInSeconds = 60 * 60 * 24 * 90;
export const actionsHandlingMiddleware = defineMiddleware( export const actionsHandlingMiddleware = defineMiddleware(async ({ url, cookies }, next) => {
async ({ url: { pathname, searchParams }, cookies }, next) => { const language = url.searchParams.get("action-lang");
const language = searchParams.get("action-lang");
if (isValidLocale(language)) { if (isValidLocale(language)) {
const currentLocale = getCurrentLocale(pathname); const currentLocale = getCurrentLocale(url.pathname);
const pathnameWithoutLocale = currentLocale const pathnameWithoutLocale = currentLocale
? pathname.substring(currentLocale.length + 1) ? url.pathname.substring(currentLocale.length + 1)
: pathname; : url.pathname;
const redirectURL = getAbsoluteLocaleUrl(language, pathnameWithoutLocale); url.pathname = getAbsoluteLocaleUrl(language, pathnameWithoutLocale);
url.searchParams.delete("action-lang");
trackEvent("action-lang"); trackEvent("action-lang");
cookies.set(CookieKeys.Language, language, { cookies.set(CookieKeys.Language, language, {
maxAge: ninetyDaysInSeconds, maxAge: ninetyDaysInSeconds,
path: "/", path: "/",
sameSite: "strict", sameSite: "strict",
}); });
return redirect(redirectURL); return redirect(url.toString());
} }
const currency = searchParams.get("action-currency"); const currency = url.searchParams.get("action-currency");
if (isValidCurrency(currency)) { if (isValidCurrency(currency)) {
trackEvent("action-currency"); trackEvent("action-currency");
cookies.set(CookieKeys.Currency, currency, { cookies.set(CookieKeys.Currency, currency, {
@ -38,10 +38,11 @@ export const actionsHandlingMiddleware = defineMiddleware(
path: "/", path: "/",
sameSite: "strict", sameSite: "strict",
}); });
return redirect(pathname); url.searchParams.delete("action-currency");
return redirect(url.toString());
} }
const theme = searchParams.get("action-theme"); const theme = url.searchParams.get("action-theme");
if (isValidTheme(theme)) { if (isValidTheme(theme)) {
trackEvent("action-theme"); trackEvent("action-theme");
cookies.set(CookieKeys.Theme, theme, { cookies.set(CookieKeys.Theme, theme, {
@ -49,9 +50,9 @@ export const actionsHandlingMiddleware = defineMiddleware(
path: "/", path: "/",
sameSite: "strict", sameSite: "strict",
}); });
return redirect(pathname); url.searchParams.delete("action-theme");
return redirect(url.toString());
} }
return next(); return next();
} });
);