diff --git a/CHANGELOG.md b/CHANGELOG.md
index ec8d31be..4b14c992 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,8 @@ and this project adheres to
- 🌐(frontend) Add German translation #255
- ✨(frontend) Add a broadcast store #387
- ✨(backend) whitelist pod's IP address #443
+- ✨(backend) config endpoint #425
+- ✨(frontend) config endpoint #424
## Changed
diff --git a/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts
new file mode 100644
index 00000000..b6a9abba
--- /dev/null
+++ b/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts
@@ -0,0 +1,29 @@
+import { expect, test } from '@playwright/test';
+
+test.describe('Config', () => {
+ test('it checks the config api is called', async ({ page }) => {
+ const responsePromise = page.waitForResponse(
+ (response) =>
+ response.url().includes('/config/') && response.status() === 200,
+ );
+
+ await page.goto('/');
+
+ const response = await responsePromise;
+ expect(response.ok()).toBeTruthy();
+
+ expect(await response.json()).toStrictEqual({
+ COLLABORATION_SERVER_URL: 'ws://localhost:4444',
+ ENVIRONMENT: 'development',
+ FRONTEND_THEME: 'dsfr',
+ MEDIA_BASE_URL: 'http://localhost:8083',
+ LANGUAGES: [
+ ['en-us', 'English'],
+ ['fr-fr', 'French'],
+ ['de-de', 'German'],
+ ],
+ LANGUAGE_CODE: 'en-us',
+ SENTRY_DSN: null,
+ });
+ });
+});
diff --git a/src/frontend/apps/impress/src/core/AppProvider.tsx b/src/frontend/apps/impress/src/core/AppProvider.tsx
index 9c6df080..39a2f962 100644
--- a/src/frontend/apps/impress/src/core/AppProvider.tsx
+++ b/src/frontend/apps/impress/src/core/AppProvider.tsx
@@ -7,6 +7,7 @@ import '@/i18n/initI18n';
import { useResponsiveStore } from '@/stores/';
import { Auth } from './auth/';
+import { ConfigProvider } from './config/';
/**
* QueryClient:
@@ -39,7 +40,9 @@ export function AppProvider({ children }: { children: React.ReactNode }) {
return (
- {children}
+
+ {children}
+
);
diff --git a/src/frontend/apps/impress/src/core/config/ConfigProvider.tsx b/src/frontend/apps/impress/src/core/config/ConfigProvider.tsx
new file mode 100644
index 00000000..f80da582
--- /dev/null
+++ b/src/frontend/apps/impress/src/core/config/ConfigProvider.tsx
@@ -0,0 +1,9 @@
+import { PropsWithChildren } from 'react';
+
+import { useConfig } from './api/useConfig';
+
+export const ConfigProvider = ({ children }: PropsWithChildren) => {
+ useConfig();
+
+ return children;
+};
diff --git a/src/frontend/apps/impress/src/core/config/api/index.ts b/src/frontend/apps/impress/src/core/config/api/index.ts
new file mode 100644
index 00000000..4852f577
--- /dev/null
+++ b/src/frontend/apps/impress/src/core/config/api/index.ts
@@ -0,0 +1 @@
+export * from './useConfig';
diff --git a/src/frontend/apps/impress/src/core/config/api/useConfig.tsx b/src/frontend/apps/impress/src/core/config/api/useConfig.tsx
new file mode 100644
index 00000000..f4b4ef7a
--- /dev/null
+++ b/src/frontend/apps/impress/src/core/config/api/useConfig.tsx
@@ -0,0 +1,33 @@
+import { useQuery } from '@tanstack/react-query';
+
+import { APIError, errorCauses, fetchAPI } from '@/api';
+
+interface ConfigResponse {
+ SENTRY_DSN: string;
+ COLLABORATION_SERVER_URL: string;
+ ENVIRONMENT: string;
+ FRONTEND_THEME: string;
+ LANGUAGES: [string, string][];
+ LANGUAGE_CODE: string;
+ MEDIA_BASE_URL: string;
+}
+
+export const getConfig = async (): Promise => {
+ const response = await fetchAPI(`config/`);
+
+ if (!response.ok) {
+ throw new APIError('Failed to get the doc', await errorCauses(response));
+ }
+
+ return response.json() as Promise;
+};
+
+export const KEY_CONFIG = 'config';
+
+export function useConfig() {
+ return useQuery({
+ queryKey: [KEY_CONFIG],
+ queryFn: () => getConfig(),
+ staleTime: Infinity,
+ });
+}
diff --git a/src/frontend/apps/impress/src/core/config/index.ts b/src/frontend/apps/impress/src/core/config/index.ts
new file mode 100644
index 00000000..feec091a
--- /dev/null
+++ b/src/frontend/apps/impress/src/core/config/index.ts
@@ -0,0 +1,2 @@
+export * from './api/useConfig';
+export * from './ConfigProvider';