From bcf4249f899cc0262c5e19b272752c599f2dddf2 Mon Sep 17 00:00:00 2001 From: Ebin Bellini Date: Wed, 22 Jul 2026 07:49:17 +0200 Subject: [PATCH 1/3] Fix Next Image fetching --- frontend/apply/src/app/about/page.tsx | 3 +-- frontend/apply/src/app/utils/imageUrl.ts | 29 ++++++++++++++++-------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/frontend/apply/src/app/about/page.tsx b/frontend/apply/src/app/about/page.tsx index eb930a5..3211849 100644 --- a/frontend/apply/src/app/about/page.tsx +++ b/frontend/apply/src/app/about/page.tsx @@ -2,7 +2,6 @@ import { useTranslation } from "react-i18next"; import Image from "next/image"; -import { getImageUrl } from "@/utils/imageUrl"; export default function About() { const { t } = useTranslation(); @@ -11,7 +10,7 @@ export default function About() {

{t("aboutPage.title")}

{t("aboutPage.introText")}

UTN members in front of our union house in winter Date: Wed, 22 Jul 2026 08:02:03 +0200 Subject: [PATCH 2/3] Fix the Next Image fix --- frontend/apply/src/app/utils/imageUrl.ts | 34 +++++++++--------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/frontend/apply/src/app/utils/imageUrl.ts b/frontend/apply/src/app/utils/imageUrl.ts index 4cabcdd..0489da8 100644 --- a/frontend/apply/src/app/utils/imageUrl.ts +++ b/frontend/apply/src/app/utils/imageUrl.ts @@ -1,39 +1,29 @@ /** * The backend returns relative paths like "/media/team_logos/dg.png". - * Next.js Image Optimization fetches the source server-side, so we must - * prepend an absolute base URL that the Next.js server can reach. * - * NEXT_PUBLIC_API_URL → derived base (strip "/api") - * Client-side → window.location.origin (nginx proxies /media/) - * SSR (Docker dev) → http://backend:8000 + * The URL returned here is used as the `src` of Next.js ``. The + * browser never loads this URL directly — it only sees the optimized + * `/_next/image?url=…` endpoint. So the URL must be reachable from + * wherever the Next.js **server** runs: * - * In production without NEXT_PUBLIC_API_URL set to an absolute URL, - * SSR-rendered pages will briefly reference "http://backend:8000" which - * won't resolve. The client hydration fixes it immediately, but the - * proper fix is to set the env var. + * Docker Compose → http://backend:8000 (default) + * Local dev → set NEXT_PUBLIC_API_URL=http://localhost:8000/api + * Production → set NEXT_PUBLIC_API_URL=https://applytest.utn.se/api */ export function getImageUrl(url: string): string { if (url.startsWith("http://") || url.startsWith("https://")) { return url; } - // Relative paths must start with /media/ – otherwise treat as local + // Paths that don't start with /media/ are local files – return as-is if (!url.startsWith("/media/")) { return url; } const apiUrl = process.env.NEXT_PUBLIC_API_URL; + const base = (apiUrl && (apiUrl.startsWith("http://") || apiUrl.startsWith("https://"))) + ? apiUrl.replace(/\/api\/?$/, "") + : "http://backend:8000"; - // Absolute env var – derive backend base from it - if (apiUrl && (apiUrl.startsWith("http://") || apiUrl.startsWith("https://"))) { - return `${apiUrl.replace(/\/api\/?$/, "")}${url}`; - } - - // Client-side – nginx proxies /media/ to Django on the same domain - if (typeof window !== "undefined") { - return `${window.location.origin}${url}`; - } - - // SSR without absolute env var – assume Docker Compose dev - return `http://backend:8000${url}`; + return `${base}${url}`; } From 5fbaddf6cd1810b37b7fe6871b3c3f27ba4f38d8 Mon Sep 17 00:00:00 2001 From: Ebin Bellini Date: Fri, 24 Jul 2026 07:55:33 +0200 Subject: [PATCH 3/3] Use origin instead of env for Image URLs --- frontend/apply/src/app/utils/imageUrl.ts | 38 ++++++++++++++++-------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/frontend/apply/src/app/utils/imageUrl.ts b/frontend/apply/src/app/utils/imageUrl.ts index 0489da8..29b136f 100644 --- a/frontend/apply/src/app/utils/imageUrl.ts +++ b/frontend/apply/src/app/utils/imageUrl.ts @@ -1,29 +1,43 @@ /** * The backend returns relative paths like "/media/team_logos/dg.png". * - * The URL returned here is used as the `src` of Next.js ``. The - * browser never loads this URL directly — it only sees the optimized - * `/_next/image?url=…` endpoint. So the URL must be reachable from - * wherever the Next.js **server** runs: + * The URL is used as the `src` of Next.js ``. The browser never + * loads it directly — it only sees `/_next/image?url=…`. So the URL + * must be reachable from the Next.js **server**. * - * Docker Compose → http://backend:8000 (default) - * Local dev → set NEXT_PUBLIC_API_URL=http://localhost:8000/api - * Production → set NEXT_PUBLIC_API_URL=https://applytest.utn.se/api + * Docker dev → http://backend:8000 (always correct inside Docker) + * Production → window.location.origin (nginx proxies /media/ to Django) + * + * Set NEXT_PUBLIC_API_URL at **build time** to an absolute URL to override + * the Docker default (e.g. for local dev: http://localhost:8000/api). */ export function getImageUrl(url: string): string { if (url.startsWith("http://") || url.startsWith("https://")) { return url; } - // Paths that don't start with /media/ are local files – return as-is + // Paths that don't start with /media/ are local Next.js files if (!url.startsWith("/media/")) { return url; } + // Build-time env var override (NEXT_PUBLIC_* are inlined at build time) const apiUrl = process.env.NEXT_PUBLIC_API_URL; - const base = (apiUrl && (apiUrl.startsWith("http://") || apiUrl.startsWith("https://"))) - ? apiUrl.replace(/\/api\/?$/, "") - : "http://backend:8000"; + if (apiUrl && (apiUrl.startsWith("http://") || apiUrl.startsWith("https://"))) { + return `${apiUrl.replace(/\/api\/?$/, "")}${url}`; + } + + // Client-side + if (typeof window !== "undefined") { + // Docker dev – don't use localhost:3000, the Next.js server needs + // to reach the backend container at backend:8000 + if (window.location.hostname === "localhost") { + return `http://backend:8000${url}`; + } + // Production – nginx proxies /media/ to Django on the same domain + return `${window.location.origin}${url}`; + } - return `${base}${url}`; + // SSR default: Docker Compose (Next.js server reaches backend:8000) + return `http://backend:8000${url}`; }