From e7eb324cb1e4e0e11fa5e840f734f60affb2aafd Mon Sep 17 00:00:00 2001 From: DrMint <29893320+DrMint@users.noreply.github.com> Date: Thu, 11 Jul 2024 23:00:56 +0200 Subject: [PATCH] Support for urls with searchparams when using server actions --- .../Topbar/components/CurrencySelector.astro | 9 +- .../Topbar/components/LanguageSelector.astro | 9 +- .../Topbar/components/ThemeSelector.astro | 13 ++- src/middleware/actionsHandling.ts | 85 ++++++++++--------- 4 files changed, 69 insertions(+), 47 deletions(-) diff --git a/src/components/AppLayout/components/Topbar/components/CurrencySelector.astro b/src/components/AppLayout/components/Topbar/components/CurrencySelector.astro index 1591326..58f0c31 100644 --- a/src/components/AppLayout/components/Topbar/components/CurrencySelector.astro +++ b/src/components/AppLayout/components/Topbar/components/CurrencySelector.astro @@ -16,6 +16,13 @@ interface Props { const { withTitle, ...otherProps } = Astro.props; 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 ------------------------------------------- */} @@ -29,7 +36,7 @@ const { t } = await getI18n(Astro.locals.currentLocale); "pressable-link", prepareClassForSelectedCurrencyPostProcessing({ currency: id }), ]} - href={`?action-currency=${id}`}> + href={getActionCurrency(id)}> {`${id} (${formatCurrency(id)})`} )) diff --git a/src/components/AppLayout/components/Topbar/components/LanguageSelector.astro b/src/components/AppLayout/components/Topbar/components/LanguageSelector.astro index f072bea..0daf10a 100644 --- a/src/components/AppLayout/components/Topbar/components/LanguageSelector.astro +++ b/src/components/AppLayout/components/Topbar/components/LanguageSelector.astro @@ -14,6 +14,13 @@ const { withTitle, ...otherProps } = Astro.props; const { currentLocale } = Astro.locals; 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 ------------------------------------------- */} @@ -24,7 +31,7 @@ const { t } = await getI18n(currentLocale); contextCache.locales.map((locale) => ( + href={getActionLanguage(locale)}> {formatLocale(locale)} )) diff --git a/src/components/AppLayout/components/Topbar/components/ThemeSelector.astro b/src/components/AppLayout/components/Topbar/components/ThemeSelector.astro index c9c3b9f..22ea23b 100644 --- a/src/components/AppLayout/components/Topbar/components/ThemeSelector.astro +++ b/src/components/AppLayout/components/Topbar/components/ThemeSelector.astro @@ -5,19 +5,26 @@ import { getI18n } from "src/i18n/i18n"; const { currentLocale } = Astro.locals; 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 ------------------------------------------- */}
- + {t("global.theme.dark")} - + {t("global.theme.auto")} - + {t("global.theme.light")}
diff --git a/src/middleware/actionsHandling.ts b/src/middleware/actionsHandling.ts index fb46569..8c9b00d 100644 --- a/src/middleware/actionsHandling.ts +++ b/src/middleware/actionsHandling.ts @@ -12,46 +12,47 @@ import { trackEvent } from "src/shared/analytics/analytics"; const ninetyDaysInSeconds = 60 * 60 * 24 * 90; -export const actionsHandlingMiddleware = defineMiddleware( - async ({ url: { pathname, searchParams }, cookies }, next) => { - const language = searchParams.get("action-lang"); - if (isValidLocale(language)) { - const currentLocale = getCurrentLocale(pathname); - const pathnameWithoutLocale = currentLocale - ? pathname.substring(currentLocale.length + 1) - : pathname; - const redirectURL = getAbsoluteLocaleUrl(language, pathnameWithoutLocale); - trackEvent("action-lang"); - cookies.set(CookieKeys.Language, language, { - maxAge: ninetyDaysInSeconds, - path: "/", - sameSite: "strict", - }); - return redirect(redirectURL); - } - - const currency = searchParams.get("action-currency"); - if (isValidCurrency(currency)) { - trackEvent("action-currency"); - cookies.set(CookieKeys.Currency, currency, { - maxAge: ninetyDaysInSeconds, - path: "/", - sameSite: "strict", - }); - return redirect(pathname); - } - - const theme = searchParams.get("action-theme"); - if (isValidTheme(theme)) { - trackEvent("action-theme"); - cookies.set(CookieKeys.Theme, theme, { - maxAge: theme === "auto" ? 0 : ninetyDaysInSeconds, - path: "/", - sameSite: "strict", - }); - return redirect(pathname); - } - - return next(); +export const actionsHandlingMiddleware = defineMiddleware(async ({ url, cookies }, next) => { + const language = url.searchParams.get("action-lang"); + if (isValidLocale(language)) { + const currentLocale = getCurrentLocale(url.pathname); + const pathnameWithoutLocale = currentLocale + ? url.pathname.substring(currentLocale.length + 1) + : url.pathname; + url.pathname = getAbsoluteLocaleUrl(language, pathnameWithoutLocale); + url.searchParams.delete("action-lang"); + trackEvent("action-lang"); + cookies.set(CookieKeys.Language, language, { + maxAge: ninetyDaysInSeconds, + path: "/", + sameSite: "strict", + }); + return redirect(url.toString()); } -); + + const currency = url.searchParams.get("action-currency"); + if (isValidCurrency(currency)) { + trackEvent("action-currency"); + cookies.set(CookieKeys.Currency, currency, { + maxAge: ninetyDaysInSeconds, + path: "/", + sameSite: "strict", + }); + url.searchParams.delete("action-currency"); + return redirect(url.toString()); + } + + const theme = url.searchParams.get("action-theme"); + if (isValidTheme(theme)) { + trackEvent("action-theme"); + cookies.set(CookieKeys.Theme, theme, { + maxAge: theme === "auto" ? 0 : ninetyDaysInSeconds, + path: "/", + sameSite: "strict", + }); + url.searchParams.delete("action-theme"); + return redirect(url.toString()); + } + + return next(); +});