From 2464dec52d4df7bbac5424b98c67ad8faffb2a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pep=20Villalonga=20Amor=C3=B3s?= Date: Fri, 10 Apr 2026 11:11:44 +0200 Subject: [PATCH 1/3] fix: inject session Astro.locals via middleware --- src/env.d.ts | 9 +++++++++ src/middleware/index.ts | 2 ++ 2 files changed, 11 insertions(+) create mode 100644 src/env.d.ts diff --git a/src/env.d.ts b/src/env.d.ts new file mode 100644 index 00000000..24547d81 --- /dev/null +++ b/src/env.d.ts @@ -0,0 +1,9 @@ +/// + +declare namespace App { + interface Locals { + lang: import("./i18n/locales/index").Locale; + t: ReturnType; + session: import("./auth/types").Session | undefined; + } +} diff --git a/src/middleware/index.ts b/src/middleware/index.ts index 19913153..9e8200f6 100644 --- a/src/middleware/index.ts +++ b/src/middleware/index.ts @@ -1,6 +1,7 @@ import { defineMiddleware } from "astro:middleware"; import { getLanguage, handleProtectedRoutes, isLanguageExemptPath } from "./utils"; +import { getSession } from "../auth/session"; import { useTranslations } from "../i18n/utils"; import type { Locale } from "../i18n/locales/index"; @@ -59,6 +60,7 @@ export const onRequest = defineMiddleware(async (context: APIContext, next) => { //throw new Error(lang); context.locals.lang = lang; context.locals.t = useTranslations(lang); + context.locals.session = await getSession(context.cookies); const redirectPath = handleProtectedRoutes(context, lang); if (redirectPath) { From 5d7acc37fe94627009fec7fcde4d26b67fde1de1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pep=20Villalonga=20Amor=C3=B3s?= Date: Fri, 10 Apr 2026 11:12:39 +0200 Subject: [PATCH 2/3] fix: add App.svelte to all pages to hydrate locale and session stores --- src/pages/[...lang]/admin/charges.astro | 4 +++- src/pages/[...lang]/checkout.astro | 4 +++- src/pages/[...lang]/index.astro | 8 ++------ src/pages/[...lang]/me.astro | 4 +++- src/pages/[...lang]/payment/index.astro | 4 +++- src/pages/[...lang]/payment/post-payment.astro | 4 +++- src/pages/[...lang]/payment/verify.astro | 4 +++- src/pages/[...lang]/payment/wallet.astro | 4 +++- src/pages/[...lang]/profile/[idOrHandle].astro | 4 +++- src/pages/[...lang]/project/[idOrSlug].astro | 4 +++- src/pages/[...lang]/register.astro | 4 +++- src/pages/[...lang]/search.astro | 4 +++- src/pages/[...lang]/static/[fileName].astro | 4 +++- 13 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/pages/[...lang]/admin/charges.astro b/src/pages/[...lang]/admin/charges.astro index 68203437..ede75c50 100644 --- a/src/pages/[...lang]/admin/charges.astro +++ b/src/pages/[...lang]/admin/charges.astro @@ -1,10 +1,12 @@ --- import Layout from "../../../layouts/Layout.astro"; -const { t } = Astro.locals; +import App from "../../../components/App.svelte"; +const { t, lang, session } = Astro.locals; import Contributions from "../../../components/Admin/Contributions.svelte"; --- +
diff --git a/src/pages/[...lang]/checkout.astro b/src/pages/[...lang]/checkout.astro index 52533cdd..a7f5ae3c 100644 --- a/src/pages/[...lang]/checkout.astro +++ b/src/pages/[...lang]/checkout.astro @@ -1,17 +1,19 @@ --- import Layout from "../../layouts/Layout.astro"; +import App from "../../components/App.svelte"; import Cart from "../../components/Checkout/Cart.svelte"; import Summary from "../../components/Checkout/Summary.svelte"; import Steps from "../../components/Checkout/Steps.svelte"; import BackButton from "../../components/BackButton.astro"; import { getPlatoniqAccountingId, getDefaultCurrency } from "../../utils/consts"; -const { t } = Astro.locals; +const { t, lang, session } = Astro.locals; const defaultCurrency = getDefaultCurrency(); const accountingIdPlatoniq = Number(getPlatoniqAccountingId() || 0); --- +
diff --git a/src/pages/[...lang]/index.astro b/src/pages/[...lang]/index.astro index e12eb735..5a2d590f 100644 --- a/src/pages/[...lang]/index.astro +++ b/src/pages/[...lang]/index.astro @@ -11,12 +11,8 @@ import FeaturedPromoters from "../../components/home/FeaturedPromoters.astro"; import Resources from "../../components/home/Resources.astro"; import Blog from "../../components/home/Blog.astro"; import Matchfunding from "../../components/home/Matchfunding.astro"; -import { getSession } from "../../auth/session"; -import type { Locale } from "../../i18n/locales"; -const { t } = Astro.locals; -const locale = Astro.currentLocale as Locale; -const session = await getSession(Astro.cookies); +const { t, lang, session } = Astro.locals; --- - + diff --git a/src/pages/[...lang]/me.astro b/src/pages/[...lang]/me.astro index 54663484..9261e7a8 100644 --- a/src/pages/[...lang]/me.astro +++ b/src/pages/[...lang]/me.astro @@ -1,5 +1,6 @@ --- import Layout from "../../layouts/Layout.astro"; +import App from "../../components/App.svelte"; import ActivitySection from "../../components/profile/ActivitySection.svelte"; import PeriodDropdown from "../../components/profile/PeriodDropdown.svelte"; import CTACard from "../../components/profile/CTACard.svelte"; @@ -7,7 +8,7 @@ import DonatedProjectsSection from "../../components/profile/DonatedProjectsSect import OwnedProjectsSection from "../../components/profile/OwnedProjectsSection.svelte"; import MatchfundingSection from "../../components/profile/MatchfundingSection.svelte"; -const { lang, t } = Astro.locals; +const { lang, t, session } = Astro.locals; const authCookie = Astro.cookies.get("auth"); if (!authCookie) { return Astro.redirect("/login?callback=/me"); @@ -19,6 +20,7 @@ const period = Astro.url.searchParams.get("period") || new Date().getFullYear(). --- +
diff --git a/src/pages/[...lang]/payment/index.astro b/src/pages/[...lang]/payment/index.astro index 51424523..7d93662e 100644 --- a/src/pages/[...lang]/payment/index.astro +++ b/src/pages/[...lang]/payment/index.astro @@ -1,5 +1,6 @@ --- import Layout from "../../../layouts/Layout.astro"; +import App from "../../../components/App.svelte"; import Summary from "../../../components/Checkout/Summary.svelte"; import PaymentMethod from "../../../components/Checkout/PaymentMethod.astro"; import Steps from "../../../components/Checkout/Steps.svelte"; @@ -9,7 +10,7 @@ import { getDefaultCurrency } from "../../../utils/consts.ts"; import { extractId } from "../../../utils/extractId"; import { apiAccountingsIdGet, apiGatewaysGetCollection } from "../../../openapi/client/index"; -const { t } = Astro.locals; +const { t, lang, session } = Astro.locals; const defaultCurrency = getDefaultCurrency(); @@ -31,6 +32,7 @@ const { data: paymentGateways } = await apiGatewaysGetCollection(); --- +
diff --git a/src/pages/[...lang]/payment/post-payment.astro b/src/pages/[...lang]/payment/post-payment.astro index 84df6e73..e1f5a3fd 100644 --- a/src/pages/[...lang]/payment/post-payment.astro +++ b/src/pages/[...lang]/payment/post-payment.astro @@ -1,5 +1,6 @@ --- import Layout from "../../../layouts/Layout.astro"; +import App from "../../../components/App.svelte"; import Carousel from "../../../components/Carousel.svelte"; import CampaignCard from "../../../components/home/CampaignCard.svelte"; import { @@ -12,7 +13,7 @@ import type { Project } from "../../../openapi/client"; import { extractId } from "../../../utils/extractId"; import type { Campaign } from "../../../types/campaign"; -const { t } = Astro.locals; +const { t, lang, session } = Astro.locals; const mapProjectToCard = (project: Project): Campaign => ({ id: project.slug || "", @@ -118,6 +119,7 @@ try { title={t("payment.postPayment.title")} description={t("payment.postPayment.certificate.description")} > +
diff --git a/src/pages/[...lang]/payment/verify.astro b/src/pages/[...lang]/payment/verify.astro index 1df66f7d..8ca5c6b1 100644 --- a/src/pages/[...lang]/payment/verify.astro +++ b/src/pages/[...lang]/payment/verify.astro @@ -1,5 +1,6 @@ --- import Layout from "../../../layouts/Layout.astro"; +import App from "../../../components/App.svelte"; import { apiAccountingsIdGet, apiGatewayCheckoutsIdGet } from "../../../openapi/client"; import FeedbackForm from "../../../components/Checkout/FeedbackForm.svelte"; import Summary from "../../../components/Checkout/Summary.svelte"; @@ -27,7 +28,7 @@ const { data: accounting } = await apiAccountingsIdGet({ }, }); -const { t } = Astro.locals; +const { t, lang, session } = Astro.locals; let error = null; let amount: number | undefined = undefined; @@ -71,6 +72,7 @@ const postPaymentUrl = checkoutId --- +
{ error ? ( diff --git a/src/pages/[...lang]/payment/wallet.astro b/src/pages/[...lang]/payment/wallet.astro index a9b7b784..949f0170 100644 --- a/src/pages/[...lang]/payment/wallet.astro +++ b/src/pages/[...lang]/payment/wallet.astro @@ -1,5 +1,6 @@ --- import Layout from "../../../layouts/Layout.astro"; +import App from "../../../components/App.svelte"; import Summary from "../../../components/Checkout/Summary.svelte"; import WalletConfirmation from "../../../components/Checkout/WalletConfirmation.astro"; import Steps from "../../../components/Checkout/Steps.svelte"; @@ -7,7 +8,7 @@ import { apiAccountingsIdGet } from "../../../openapi/client/index"; import { getDefaultCurrency } from "../../../utils/consts.ts"; import { extractId } from "../../../utils/extractId"; -const { t } = Astro.locals; +const { t, lang, session } = Astro.locals; const defaultCurrency = getDefaultCurrency(); const authCookie = Astro.cookies.get("auth"); @@ -25,6 +26,7 @@ const { data: accounting } = await apiAccountingsIdGet({ --- +
diff --git a/src/pages/[...lang]/profile/[idOrHandle].astro b/src/pages/[...lang]/profile/[idOrHandle].astro index baa4b38a..b3e59a2b 100644 --- a/src/pages/[...lang]/profile/[idOrHandle].astro +++ b/src/pages/[...lang]/profile/[idOrHandle].astro @@ -1,5 +1,6 @@ --- import Layout from "../../../layouts/Layout.astro"; +import App from "../../../components/App.svelte"; import ProfileHero from "../../../components/profile/ProfileHero.astro"; import ProfileInfo from "../../../components/profile/ProfileInfo.svelte"; import Tabs from "../../../components/Tabs.svelte"; @@ -20,7 +21,7 @@ import { getLanguage } from "../../../middleware/utils"; import { client } from "../../../openapi/client/client.gen"; const { idOrHandle } = Astro.params; -const { t } = Astro.locals; +const { t, lang, session } = Astro.locals; if (!idOrHandle) { return Astro.redirect("/404"); @@ -165,6 +166,7 @@ const avatarImage = user?.avatar || undefined; // Use user avatar or default pla description={`${t("profile.tabs.about")} ${displayName}`} class="mb-20" > + { errorMessage ? (
diff --git a/src/pages/[...lang]/project/[idOrSlug].astro b/src/pages/[...lang]/project/[idOrSlug].astro index ebf9ddda..c49e79f9 100644 --- a/src/pages/[...lang]/project/[idOrSlug].astro +++ b/src/pages/[...lang]/project/[idOrSlug].astro @@ -1,6 +1,7 @@ --- import SingleProject from "../../../components/project/SingleProject.svelte"; import Layout from "../../../layouts/Layout.astro"; +import App from "../../../components/App.svelte"; import { extractId } from "../../../utils/extractId"; const { idOrSlug } = Astro.params; @@ -17,7 +18,7 @@ if (!idOrSlug) { throw new Error("Project ID or Project Slug is undefined."); } -let lang = Astro.locals.lang; +const { lang, session } = Astro.locals; const { data: project, error } = await apiProjectsIdOrSlugGet({ path: { idOrSlug }, @@ -65,6 +66,7 @@ const { data: balancePoints } = await apiAccountingBalancePointsGetCollection({ --- + { @@ -18,6 +19,7 @@ itemCount.subscribe((count) => { --- +
diff --git a/src/pages/[...lang]/search.astro b/src/pages/[...lang]/search.astro index ee1d4bf5..f5bbc295 100644 --- a/src/pages/[...lang]/search.astro +++ b/src/pages/[...lang]/search.astro @@ -1,11 +1,12 @@ --- import Layout from "../../layouts/Layout.astro"; +import App from "../../components/App.svelte"; import SearchFilters from "../../components/search/SearchFilters.svelte"; import SearchResultsClient from "../../components/search/SearchResultsClient.svelte"; import type { Project } from "../../openapi/client/types.gen"; -const { t, lang } = Astro.locals; +const { t, lang, session } = Astro.locals; // Initial projects will be fetched client-side to avoid blocking SSR const initialProjects: Project[] = []; @@ -27,6 +28,7 @@ const hasInitialSearch = !!( --- +
diff --git a/src/pages/[...lang]/static/[fileName].astro b/src/pages/[...lang]/static/[fileName].astro index 2e30f7e3..c398c7ac 100644 --- a/src/pages/[...lang]/static/[fileName].astro +++ b/src/pages/[...lang]/static/[fileName].astro @@ -1,9 +1,10 @@ --- import Layout from "../../../layouts/Layout.astro"; +import App from "../../../components/App.svelte"; import ReturnHeader from "../../../components/library/ReturnHeader.svelte"; import BodyText from "../../../components/library/BodyText.svelte"; -const { t } = Astro.locals; +const { t, lang, session } = Astro.locals; const { fileName } = Astro.params; const markdownFiles = import.meta.glob<{ default: any }>("../../../../static/*md"); @@ -24,6 +25,7 @@ const Content = file.default; description={t("metadata.description")} class="mb-20 gap-[72px]" > + From 9c7bb594d707dfa6931f1b358a7b082b0ef4270d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pep=20Villalonga=20Amor=C3=B3s?= Date: Fri, 10 Apr 2026 14:12:00 +0200 Subject: [PATCH 3/3] fix: consolidate App.Locals types into root env.d.ts --- env.d.ts | 14 +++++--------- src/env.d.ts | 9 --------- 2 files changed, 5 insertions(+), 18 deletions(-) delete mode 100644 src/env.d.ts diff --git a/env.d.ts b/env.d.ts index a2f7737a..b7978771 100644 --- a/env.d.ts +++ b/env.d.ts @@ -1,13 +1,9 @@ /// -/* eslint-disable @typescript-eslint/no-unused-vars */ -import type { useTranslations } from "./i18n/utils"; -import type { Locale } from "../i18n/locales/index"; -declare global { - namespace App { - interface Locals { - lang: import("./i18n/store").Locale; - t: ReturnType; - } +declare namespace App { + interface Locals { + lang: import("./src/i18n/locales/index").Locale; + t: ReturnType; + session: import("./src/auth/types").Session | undefined; } } diff --git a/src/env.d.ts b/src/env.d.ts deleted file mode 100644 index 24547d81..00000000 --- a/src/env.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -/// - -declare namespace App { - interface Locals { - lang: import("./i18n/locales/index").Locale; - t: ReturnType; - session: import("./auth/types").Session | undefined; - } -}