Voeg VITE_API_BASE_URL toe voor lokale API-calls naar een losse backend #12

Merged
Sluijsens merged 2 commits from feature/local-api-base-url into master 2026-08-02 16:01:01 +02:00
4 changed files with 23 additions and 3 deletions
+5
View File
@@ -15,3 +15,8 @@ VITE_SENTRY_DSN=
# script sowieso nooit geladen, ongeacht deze waarden (zie UmamiAnalytics.tsx). # script sowieso nooit geladen, ongeacht deze waarden (zie UmamiAnalytics.tsx).
VITE_UMAMI_SCRIPT_URL=https://analytics.slpsoftware.nl/script.js VITE_UMAMI_SCRIPT_URL=https://analytics.slpsoftware.nl/script.js
VITE_UMAMI_WEBSITE_ID= VITE_UMAMI_WEBSITE_ID=
# API base URL override, alleen voor lokale development met een lokaal draaiende backend.
# Laat leeg/weg op test en productie: dan blijven API-calls relatief (`/api/v1/...`),
# zodat ze resolven tegen hetzelfde domein als de site (test.slpsoftware.nl / slpsoftware.nl).
VITE_API_BASE_URL=https://localhost:7223
@@ -1,5 +1,5 @@
import { render, screen, waitFor } from '@testing-library/react'; import { render, screen, waitFor } from '@testing-library/react';
import { describe, it, expect, vi, afterEach } from 'vitest'; import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { PackagesSection } from '../components/PackagesSection'; import { PackagesSection } from '../components/PackagesSection';
import { packages } from '../data/content'; import { packages } from '../data/content';
@@ -23,8 +23,15 @@ function mockFetchOnce(response: Response) {
} }
describe('PackagesSection', () => { describe('PackagesSection', () => {
beforeEach(() => {
// Force a deterministic relative URL regardless of the developer's local
// .env.local (VITE_API_BASE_URL is only meant to override this outside tests).
vi.stubEnv('VITE_API_BASE_URL', '');
});
afterEach(() => { afterEach(() => {
vi.unstubAllGlobals(); vi.unstubAllGlobals();
vi.unstubAllEnvs();
}); });
it('fetches packages from /api/v1/offerings and renders one PackageCard per package', async () => { it('fetches packages from /api/v1/offerings and renders one PackageCard per package', async () => {
@@ -5,10 +5,16 @@ import type { PackageCardData } from '../data/content';
// (test.slpsoftware.nl / slpsoftware.nl) — see aidlc-docs/features/react-frontend/ // (test.slpsoftware.nl / slpsoftware.nl) — see aidlc-docs/features/react-frontend/
// construction/react-frontend-app/functional-design/packages-api-handoff.md // construction/react-frontend-app/functional-design/packages-api-handoff.md
// for the API contract this endpoint must implement. // for the API contract this endpoint must implement.
const OFFERINGS_ENDPOINT = '/api/v1/offerings'; // VITE_API_BASE_URL is only set locally (.env.local, e.g. https://localhost:7223) to
// point at a locally running backend; on test/production it's unset, so the path stays
// relative to whichever origin served the app. Read inside the function (not as a
// module-level constant) so tests can stub it per-case.
function offeringsEndpoint() {
return `${import.meta.env.VITE_API_BASE_URL ?? ''}/api/v1/offerings`;
}
async function fetchPackages(): Promise<PackageCardData[]> { async function fetchPackages(): Promise<PackageCardData[]> {
const response = await fetch(OFFERINGS_ENDPOINT); const response = await fetch(offeringsEndpoint());
if (!response.ok) { if (!response.ok) {
throw new Error(`Failed to fetch packages: ${response.status} ${response.statusText}`); throw new Error(`Failed to fetch packages: ${response.status} ${response.statusText}`);
} }
+2
View File
@@ -9,6 +9,8 @@ interface ImportMetaEnv {
readonly VITE_SENTRY_DSN?: string; readonly VITE_SENTRY_DSN?: string;
/** Build-time deployment environment tag ('test' | 'production' | undefined). Used to hide dev/test-only UI (e.g. SentryTestButton) from production builds. */ /** Build-time deployment environment tag ('test' | 'production' | undefined). Used to hide dev/test-only UI (e.g. SentryTestButton) from production builds. */
readonly VITE_APP_ENV?: string; readonly VITE_APP_ENV?: string;
/** API base URL override for local development (e.g. https://localhost:7223). Leave unset on test/production so API calls stay relative to `/api/v1/...` on the same origin. */
readonly VITE_API_BASE_URL?: string;
} }
interface ImportMeta { interface ImportMeta {