diff --git a/README.md b/README.md
index 8f28066ae36b5b7d900bf0ce3c90c3f8494b38f4..6f3bdba6e3326c9d4d21079c7102ae930f61594f 100644
--- a/README.md
+++ b/README.md
@@ -15,8 +15,8 @@ $ git clone https://git.duniter.org/paidge/wotwizard-ui.git
 $ cd wotwizard-ui
 # If you want to use the git's hook to prevent commits if language strings are missing
 $ git config --local core.hooksPath .githooks/
-# To be sure to use Node 16
-$ nvm use 16
+# To be sure to use Node 20
+$ nvm use 20
 # Create your branch
 $ git checkout -b my-branch
 # Install the dependencies of the project
@@ -34,6 +34,10 @@ $ git push
 
 Then create a merge request.
 
+### Add new wotwizard graphql endpoint
+
+Just add your new endpoint in `endpoints.json` file and rebuild app.
+
 ### Add a new page
 
 Copy/paste the file `./pages/template.vue` and rename it to create a new page.
diff --git a/endpoints.json b/endpoints.json
new file mode 100644
index 0000000000000000000000000000000000000000..ebb1e514d67a7b9b302c94e30b007853b54add66
--- /dev/null
+++ b/endpoints.json
@@ -0,0 +1,4 @@
+{
+    "AxiomTeam": "https://gql.wotwizard.axiom-team.fr/",
+    "trentesaux": "https://gql.wotwizard.trentesaux.fr/"
+}
diff --git a/graphql/endpoints/AxiomTeam.js b/graphql/endpoints/AxiomTeam.js
new file mode 100644
index 0000000000000000000000000000000000000000..342be03d0917e8a2065a162b1150bf24aab3aff3
--- /dev/null
+++ b/graphql/endpoints/AxiomTeam.js
@@ -0,0 +1,19 @@
+
+const { HttpLink } = require("apollo-link-http");
+const { setContext } = require("apollo-link-context");
+const { from } = require("apollo-link");
+const { cache } = require("../cache");
+
+const ssrMiddleware = setContext((_, { headers }) => {
+    if (process.client) return headers;
+    return { headers };
+});
+
+const httpLink = new HttpLink({ uri: "https://gql.wotwizard.axiom-team.fr/" });
+const link = from([ssrMiddleware, httpLink]);
+
+module.exports = () => ({
+    link,
+    cache,
+    defaultHttpLink: false
+});
diff --git a/graphql/endpoints/axiom-team.js b/graphql/endpoints/axiom-team.js
deleted file mode 100644
index 12cfe2fd6c74c674c7e2f86586183861afa834af..0000000000000000000000000000000000000000
--- a/graphql/endpoints/axiom-team.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import { HttpLink } from "apollo-link-http"
-import { setContext } from "apollo-link-context"
-import { from } from "apollo-link"
-import { cache } from "../cache"
-
-export default (ctx) => {
-	const ssrMiddleware = setContext((_, { headers }) => {
-		if (process.client) return headers
-		return {
-			headers
-		}
-	})
-
-	const httpLink = new HttpLink({
-		uri: "https://gql.wotwizard.axiom-team.fr/"
-	})
-
-	const link = from([ssrMiddleware, httpLink])
-
-	return {
-		link,
-		cache,
-		// https://github.com/nuxt-community/apollo-module/issues/306#issuecomment-607225431
-		defaultHttpLink: false
-	}
-}
diff --git a/graphql/endpoints/trentesaux.js b/graphql/endpoints/trentesaux.js
index 464caf49a5213f07136586d6c1646a4b15474fcc..d74f69fb2c493e3c969439cf5220b3b8fd0bbb59 100644
--- a/graphql/endpoints/trentesaux.js
+++ b/graphql/endpoints/trentesaux.js
@@ -1,26 +1,19 @@
-import { HttpLink } from "apollo-link-http"
-import { setContext } from "apollo-link-context"
-import { from } from "apollo-link"
-import { cache } from "../cache"
 
-export default (ctx) => {
-	const ssrMiddleware = setContext((_, { headers }) => {
-		if (process.client) return headers
-		return {
-			headers
-		}
-	})
+const { HttpLink } = require("apollo-link-http");
+const { setContext } = require("apollo-link-context");
+const { from } = require("apollo-link");
+const { cache } = require("../cache");
 
-	const httpLink = new HttpLink({
-		uri: "https://gql.wotwizard.trentesaux.fr/"
-	})
+const ssrMiddleware = setContext((_, { headers }) => {
+    if (process.client) return headers;
+    return { headers };
+});
 
-	const link = from([ssrMiddleware, httpLink])
+const httpLink = new HttpLink({ uri: "https://gql.wotwizard.trentesaux.fr/" });
+const link = from([ssrMiddleware, httpLink]);
 
-	return {
-		link,
-		cache,
-		// https://github.com/nuxt-community/apollo-module/issues/306#issuecomment-607225431
-		defaultHttpLink: false
-	}
-}
+module.exports = () => ({
+    link,
+    cache,
+    defaultHttpLink: false
+});
diff --git a/graphql/generateEndpoints.js b/graphql/generateEndpoints.js
new file mode 100644
index 0000000000000000000000000000000000000000..dd51a1e7a96664f3d9b378fb70f6e373577003e9
--- /dev/null
+++ b/graphql/generateEndpoints.js
@@ -0,0 +1,42 @@
+const fs = require('fs');
+const path = require('path');
+const endpoints = require('../endpoints.json');
+
+const endpointDir = path.join(__dirname, 'endpoints');
+
+const recreateDirectory = (directory) => {
+  if (fs.existsSync(directory)) {
+    fs.rmSync(directory, { recursive: true, force: true });
+  }
+
+  fs.mkdirSync(directory, { recursive: true });
+};
+
+recreateDirectory(endpointDir);
+
+const configTemplate = (uri) => `
+const { HttpLink } = require("apollo-link-http");
+const { setContext } = require("apollo-link-context");
+const { from } = require("apollo-link");
+const { cache } = require("../cache");
+
+const ssrMiddleware = setContext((_, { headers }) => {
+    if (process.client) return headers;
+    return { headers };
+});
+
+const httpLink = new HttpLink({ uri: "${uri}" });
+const link = from([ssrMiddleware, httpLink]);
+
+module.exports = () => ({
+    link,
+    cache,
+    defaultHttpLink: false
+});
+`;
+
+Object.keys(endpoints).forEach(key => {
+  const filePath = path.join(endpointDir, `${key}.js`);
+  const fileContent = configTemplate(endpoints[key]);
+  fs.writeFileSync(filePath, fileContent);
+});
diff --git a/nuxt.config.js b/nuxt.config.js
index 3cbb29853fce3b12f9ceb3e751db031e7f66571b..c2f4b1134460df2c4afefef639edd3aca2fc70a8 100644
--- a/nuxt.config.js
+++ b/nuxt.config.js
@@ -1,4 +1,5 @@
-import i18n from "./i18n"
+const i18n = require("./i18n");
+const endpoints = require('./endpoints.json');
 
 export default {
 	// Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode
@@ -114,10 +115,10 @@ export default {
 	},
 
 	apollo: {
-		clientConfigs: {
-			trentesaux: "~/graphql/endpoints/trentesaux",
-			axiomTeam: "~/graphql/endpoints/axiom-team"
-		}
+		clientConfigs: Object.keys(endpoints).reduce((configs, key) => {
+			configs[key] = `~/graphql/endpoints/${key}.js`;
+			return configs;
+		}, {}),
 	},
 
 	router: {
diff --git a/package.json b/package.json
index 0fb3f1abfdcdc0da7825ce0d3d123b34b124604e..8fea86a085291a1f6aa05f8455ac4df50403df6e 100644
--- a/package.json
+++ b/package.json
@@ -3,9 +3,10 @@
 	"version": "2.5.2",
 	"private": true,
 	"scripts": {
-		"dev": "nuxt",
+		"dev": "npm run generate-endpoints && nuxt",
 		"trad": "sh ./utils/findMissingI18nKeys.sh",
-		"build": "npm-run-all -p build-fragment nuxt-build",
+		"generate-endpoints": "node graphql/generateEndpoints.js",
+		"build": "npm run generate-endpoints && npm-run-all -p build-fragment nuxt-build",
 		"start": "npm-run-all -p build-fragment nuxt-start",
 		"generate": "npm-run-all -p build-fragment nuxt-generate && cp ./web-ext/* ./dist/",
 		"analyze": "nuxt build --analyze",
@@ -24,6 +25,7 @@
 		"bootstrap": "5.1.3",
 		"core-js": "^3.15.1",
 		"graphql-tag": "^2.12.6",
+		"node-fetch": "^3.3.2",
 		"nuxt": "^2.15.8",
 		"vue": "^2.6.14"
 	},