diff --git a/.env.local.example b/.env.local.example new file mode 100644 index 0000000..5e55329 --- /dev/null +++ b/.env.local.example @@ -0,0 +1 @@ +CMS_URL= \ No newline at end of file diff --git a/README.md b/README.md index 1319f22..dc9aa5d 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,9 @@ # Running 1. Install [node](https://nodejs.org/en) -2. Run `npm install` -3. Run `npm run dev` to start a local development server +2. Rename `.env.local.example` and set the CMS_URL +3. Run `npm install` +4. Run `npm run dev` to start a local development server # Development workflow @@ -14,6 +15,8 @@ 3. Verify your changes through the "preview", the link will appear as a comment in the PR. 4. If everything is okay, merge the PR. The main branch is automatically deployed to production. +A file `translations.json` is downloaded from the CMS every time you run a command. This allows Typescript to use it's type data for autocompleting and build-time verifying translation keys. + ## License This project contains both code and content. The code of the website is licensed under GPLv3. By content we mean text, image, logos or designs specific to the Satakunta Nation. The content is proprietary. In other words, you can freely use the technical implementation (code, config files) of this website for your purposes, but make your own content. diff --git a/fetchTranslations.mjs b/fetchTranslations.mjs new file mode 100644 index 0000000..84723c1 --- /dev/null +++ b/fetchTranslations.mjs @@ -0,0 +1,34 @@ +import dotenv from "dotenv"; +dotenv.config({ path: ".env.local" }); +import { writeFile } from "fs/promises"; + +export async function fetchTranslations() { + if (process.env.CMS_URL === undefined) { + console.error("CMS_URL is not defined. Could not fetch translations."); + return; + } + + try { + console.log("Fetching translations.json"); + const response = await fetch(process.env.CMS_URL + "/items/text"); + if (!response.ok) { + throw new Error( + `Failed to download translations: ${response.statusText}`, + ); + } + + const data = await response.json(); + + await writeFile( + "./hooks/translations.json", + JSON.stringify(data, null, 2) + "\n", + ); // prettier wants a trailing newline + console.log( + `Downloaded and saved translations.json ${response.status === 304 ? "cached" : ""}`, + ); + } catch (error) { + console.error("Error downloading translations.json :", error); + } +} + +fetchTranslations(); diff --git a/hooks/translations.json b/hooks/translations.json new file mode 100644 index 0000000..c501849 --- /dev/null +++ b/hooks/translations.json @@ -0,0 +1,22 @@ +{ + "data": [ + { + "key": "new_test", + "text_fi": "moi", + "text_en": "hi", + "text_sv": "hej" + }, + { + "key": "general:nation", + "text_fi": "Satakuntalainen Osakunta", + "text_en": "Satakunta Nation", + "text_sv": "Satakunta Nation" + }, + { + "key": "home:welcome", + "text_fi": "Tervetuloa Satakuntalaisen Osakunnan sivuille", + "text_en": "Welcome to the website of Satakuntalainen Osakunta", + "text_sv": "Samma på svenska" + } + ] +} diff --git a/next.config.mjs b/next.config.mjs index 366c433..a99d7bd 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,10 +1,16 @@ -/** @type {import('next').NextConfig} */ -const nextConfig = { - output: "export", - images: { - unoptimized: true, - }, - reactStrictMode: true, +const config = async () => { + /** + * @type {import('next').NextConfig} + */ + const nextConfig = { + output: "export", + images: { + unoptimized: true, + }, + reactStrictMode: true, + }; + + return nextConfig; }; -export default nextConfig; +export default config; diff --git a/package.json b/package.json index 2f41d6e..e2e9264 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "format": "prettier . --write", "test:watch": "vitest", "test": "vitest run", - "prepare": "husky" + "fetchTranslations": "node fetchTranslations.mjs", + "prepare": "husky && npm run fetchTranslations" }, "dependencies": { "@emotion/react": "^11.11.4",