From 740cba625dfc6a708872becbaae237fd068122f4 Mon Sep 17 00:00:00 2001 From: Martin Berg Alstad Date: Sat, 12 Oct 2024 18:29:44 +0200 Subject: [PATCH] SSR and i18n Signed-off-by: Martin Berg Alstad --- .gitea/workflows/build.yaml | 1 + astro.config.mjs | 18 ++- messages/en.json | 5 +- messages/nb.json | 5 +- package.json | 3 +- pnpm-lock.yaml | 150 ++++++++++++++++++ src/components/Footer.astro | 25 +-- src/components/LanguageButtonGroup.astro | 11 ++ src/components/LanguageButtonGroup.svelte | 17 -- src/components/Navbar.astro | 9 +- src/components/links/LocaleLink.astro | 16 ++ src/links.ts | 25 ++- src/pages/{contact-me.astro => contact.astro} | 0 .../en/{contact-me.astro => contact.astro} | 0 .../en/{project => projects}/[project].astro | 2 + .../en/{project => projects}/index.astro | 0 .../{project => projects}/[project].astro | 2 + src/pages/{project => projects}/index.astro | 0 src/types/types.ts | 1 + src/utils/linking.ts | 45 ++++-- 20 files changed, 273 insertions(+), 62 deletions(-) create mode 100644 src/components/LanguageButtonGroup.astro delete mode 100644 src/components/LanguageButtonGroup.svelte create mode 100644 src/components/links/LocaleLink.astro rename src/pages/{contact-me.astro => contact.astro} (100%) rename src/pages/en/{contact-me.astro => contact.astro} (100%) rename src/pages/en/{project => projects}/[project].astro (92%) rename src/pages/en/{project => projects}/index.astro (100%) rename src/pages/{project => projects}/[project].astro (92%) rename src/pages/{project => projects}/index.astro (100%) create mode 100644 src/types/types.ts diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 05f1cfa..91fa881 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -25,6 +25,7 @@ jobs: name: dist path: dist + # TODO update deploy to work with node deploy: runs-on: host diff --git a/astro.config.mjs b/astro.config.mjs index 0aaeb83..0d81d35 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,14 +1,15 @@ // @ts-check -import { defineConfig } from "astro/config" +import paraglide from "@inlang/paraglide-astro" import tailwind from "@astrojs/tailwind" import sitemap from "@astrojs/sitemap" -import paraglide from "@inlang/paraglide-astro" -import { loadEnv } from "vite" -import mdx from "@astrojs/mdx" import svelte from "@astrojs/svelte" - +import node from "@astrojs/node" +import mdx from "@astrojs/mdx" import icon from "astro-icon" +import { defineConfig } from "astro/config" +import { loadEnv } from "vite" + const { url } = process.env.URL ? loadEnv(process.env.URL, process.cwd(), "") : { url: "http://localhost:3000" } @@ -16,7 +17,7 @@ const { url } = process.env.URL // https://astro.build/config export default defineConfig({ site: url, - // output: "server", TODO server | also required for i18n + output: "server", i18n: { defaultLocale: "nb", locales: ["nb", "en"] @@ -32,5 +33,8 @@ export default defineConfig({ project: "./project.inlang", outdir: "./src/paraglide" //where your files should be }) - ] + ], + adapter: node({ + mode: "standalone" + }) }) \ No newline at end of file diff --git a/messages/en.json b/messages/en.json index f0c9ee4..9548e63 100644 --- a/messages/en.json +++ b/messages/en.json @@ -18,5 +18,8 @@ "subject": "Subject", "email": "Email", "message": "Message", - "send": "Send" + "send": "Send", + "auto": "Auto", + "norwegian": "Norwegian", + "english": "English" } diff --git a/messages/nb.json b/messages/nb.json index 86ac2d9..a577265 100644 --- a/messages/nb.json +++ b/messages/nb.json @@ -18,5 +18,8 @@ "subject": "Emne", "email": "E-post", "message": "Melding", - "send": "Send" + "send": "Send", + "auto": "Auto", + "norwegian": "Norsk", + "english": "Engelsk" } diff --git a/package.json b/package.json index 9569418..ee1445e 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,12 @@ "astro": "astro", "postinstall": "paraglide-js compile --project ./project.inlang --outdir ./src/paraglide", "format": "prettier --write \"./src/**/*.{js,mjs,ts,astro,svelte,css,md,json}\"", - "watch-translations": "paraglide-js compile --watch --project ./project.inlang --outdir ./src/paraglide" + "watch-messages": "paraglide-js compile --watch --project ./project.inlang --outdir ./src/paraglide" }, "dependencies": { "@astrojs/check": "^0.9.3", "@astrojs/mdx": "^3.1.7", + "@astrojs/node": "^8.3.4", "@astrojs/sitemap": "^3.1.6", "@astrojs/svelte": "^5.7.1", "@astrojs/tailwind": "^5.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7a000c8..88f6423 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@astrojs/mdx': specifier: ^3.1.7 version: 3.1.7(astro@4.15.9(rollup@4.21.2)(typescript@5.6.2)) + '@astrojs/node': + specifier: ^8.3.4 + version: 8.3.4(astro@4.15.9(rollup@4.21.2)(typescript@5.6.2)) '@astrojs/sitemap': specifier: ^3.1.6 version: 3.1.6 @@ -119,6 +122,11 @@ packages: peerDependencies: astro: ^4.8.0 + '@astrojs/node@8.3.4': + resolution: {integrity: sha512-xzQs39goN7xh9np9rypGmbgZj3AmmjNxEMj9ZWz5aBERlqqFF3n8A/w/uaJeZ/bkHS60l1BXVS0tgsQt9MFqBA==} + peerDependencies: + astro: ^4.2.0 + '@astrojs/prism@3.1.0': resolution: {integrity: sha512-Z9IYjuXSArkAUx3N6xj6+Bnvx8OdUSHA8YoOgyepp3+zJmtVYJIl/I18GozdJVW1p5u/CNpl3Km7/gwTJK85cw==} engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0} @@ -1291,6 +1299,14 @@ packages: resolution: {integrity: sha512-jp1RAuzbHhGdXmn957Z2XsTZStXGHzFfF0FgIOZj3Wv9sH7OZgLfXTRZNfKVYxltGUOBsG1kbWAdF5SrqjebvA==} engines: {node: '>=16.9.0'} + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@4.3.7: resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} engines: {node: '>=6.0'} @@ -1326,6 +1342,10 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + deprecation@2.3.1: resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} @@ -1333,6 +1353,10 @@ packages: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + detect-libc@2.0.3: resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} engines: {node: '>=8'} @@ -1380,6 +1404,9 @@ packages: ecdsa-sig-formatter@1.0.11: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + electron-to-chromium@1.5.18: resolution: {integrity: sha512-1OfuVACu+zKlmjsNdcJuVQuVE61sZOLbNM4JAQ1Rvh6EOj0/EUKhMJjRH73InPlXSh8HIJk1cVZ8pyOV/FMdUQ==} @@ -1395,6 +1422,10 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + encoding-sniffer@0.2.0: resolution: {integrity: sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==} @@ -1417,6 +1448,9 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} @@ -1451,6 +1485,10 @@ packages: estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} @@ -1524,6 +1562,10 @@ packages: fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + fs-minipass@2.1.0: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} engines: {node: '>= 8'} @@ -1638,6 +1680,10 @@ packages: http-cache-semantics@4.1.1: resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -2066,6 +2112,11 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + mimic-function@5.0.1: resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} engines: {node: '>=18'} @@ -2106,6 +2157,9 @@ packages: resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} engines: {node: '>=10'} + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -2160,6 +2214,10 @@ packages: resolution: {integrity: sha512-MG5qmrTL5y8KYwFgE1A4JWmgfQBaIETE/lOlfwNYx1QOtCQHGVxkRJmdUJltFc1HVn73d61TlMhMyNTOtMl+ng==} engines: {node: '>= 18'} + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -2372,6 +2430,10 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + read-cache@1.0.0: resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} @@ -2487,6 +2549,16 @@ packages: engines: {node: '>=10'} hasBin: true + send@0.19.1: + resolution: {integrity: sha512-p4rRk4f23ynFEfcD9LA0xRYngj+IyGiEYyqqOak8kaN0TvNmuxC2dcVeBn62GpCeR2CpWqyHCNScTP91QbAVFg==} + engines: {node: '>= 0.8.0'} + + server-destroy@1.0.1: + resolution: {integrity: sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + sha.js@2.4.11: resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} hasBin: true @@ -2538,6 +2610,10 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + stdin-discarder@0.2.2: resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} engines: {node: '>=18'} @@ -2650,6 +2726,10 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} @@ -3121,6 +3201,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@astrojs/node@8.3.4(astro@4.15.9(rollup@4.21.2)(typescript@5.6.2))': + dependencies: + astro: 4.15.9(rollup@4.21.2)(typescript@5.6.2) + send: 0.19.1 + server-destroy: 1.0.1 + transitivePeerDependencies: + - supports-color + '@astrojs/prism@3.1.0': dependencies: prismjs: 1.29.0 @@ -4514,6 +4602,10 @@ snapshots: transitivePeerDependencies: - postcss + debug@2.6.9: + dependencies: + ms: 2.0.0 + debug@4.3.7: dependencies: ms: 2.1.3 @@ -4532,10 +4624,14 @@ snapshots: delayed-stream@1.0.0: {} + depd@2.0.0: {} + deprecation@2.3.1: {} dequal@2.0.3: {} + destroy@1.2.0: {} + detect-libc@2.0.3: {} deterministic-object-hash@2.0.2: @@ -4580,6 +4676,8 @@ snapshots: dependencies: safe-buffer: 5.2.1 + ee-first@1.1.1: {} + electron-to-chromium@1.5.18: {} emmet@2.4.7: @@ -4593,6 +4691,8 @@ snapshots: emoji-regex@9.2.2: {} + encodeurl@2.0.0: {} + encoding-sniffer@0.2.0: dependencies: iconv-lite: 0.6.3 @@ -4634,6 +4734,8 @@ snapshots: escalade@3.2.0: {} + escape-html@1.0.3: {} + escape-string-regexp@1.0.5: {} escape-string-regexp@5.0.0: {} @@ -4670,6 +4772,8 @@ snapshots: dependencies: '@types/estree': 1.0.5 + etag@1.8.1: {} + eventemitter3@5.0.1: {} extend-shallow@2.0.1: @@ -4743,6 +4847,8 @@ snapshots: fraction.js@4.3.7: {} + fresh@0.5.2: {} + fs-minipass@2.1.0: dependencies: minipass: 3.3.6 @@ -4941,6 +5047,14 @@ snapshots: http-cache-semantics@4.1.1: {} + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 @@ -5601,6 +5715,8 @@ snapshots: dependencies: mime-db: 1.52.0 + mime@1.6.0: {} + mimic-function@5.0.1: {} minimatch@9.0.5: @@ -5633,6 +5749,8 @@ snapshots: mrmime@2.0.0: {} + ms@2.0.0: {} + ms@2.1.3: {} muggle-string@0.4.1: {} @@ -5685,6 +5803,10 @@ snapshots: '@octokit/request-error': 5.1.0 '@octokit/types': 12.6.0 + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + once@1.4.0: dependencies: wrappy: 1.0.2 @@ -5904,6 +6026,8 @@ snapshots: queue-microtask@1.2.3: {} + range-parser@1.2.1: {} + read-cache@1.0.0: dependencies: pify: 2.3.0 @@ -6080,6 +6204,28 @@ snapshots: semver@7.6.3: {} + send@0.19.1: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + server-destroy@1.0.1: {} + + setprototypeof@1.2.0: {} + sha.js@2.4.11: dependencies: inherits: 2.0.4 @@ -6150,6 +6296,8 @@ snapshots: sprintf-js@1.0.3: {} + statuses@2.0.1: {} + stdin-discarder@0.2.2: {} stream-replace-string@2.0.0: {} @@ -6309,6 +6457,8 @@ snapshots: dependencies: is-number: 7.0.0 + toidentifier@1.0.1: {} + trim-lines@3.0.1: {} trough@2.2.0: {} diff --git a/src/components/Footer.astro b/src/components/Footer.astro index d61ee09..e6f4c7b 100644 --- a/src/components/Footer.astro +++ b/src/components/Footer.astro @@ -1,20 +1,21 @@ --- import GiteaLink from "./links/GiteaLink.astro" -import ExternalLink from "./links/ExternalLink.astro" import PajamasIcon from "./icons/PajamasIcon.astro" -import LanguageButtonGroup from "./LanguageButtonGroup.svelte" +import ExternalLink from "./links/ExternalLink.astro" +import LanguageButtonGroup from "./LanguageButtonGroup.astro" import * as m from "@/paraglide/messages" -const gitUrl = import.meta.env.GIT_URL -const statusUrl = import.meta.env.STATUS_URL +const { GIT_URL, STATUS_URL } = import.meta.env --- -
-
- - - - - {m.status()} - +
+
+
+ + + + {m.status()} + +
+
diff --git a/src/components/LanguageButtonGroup.astro b/src/components/LanguageButtonGroup.astro new file mode 100644 index 0000000..ba09225 --- /dev/null +++ b/src/components/LanguageButtonGroup.astro @@ -0,0 +1,11 @@ +--- +import LocaleLink from "./links/LocaleLink.astro" +import { type NavLink, resolvePathname } from "@/utils/linking" + +const currentPath = resolvePathname(Astro.url.pathname) +--- + +
+ Norsk + English +
diff --git a/src/components/LanguageButtonGroup.svelte b/src/components/LanguageButtonGroup.svelte deleted file mode 100644 index 95db333..0000000 --- a/src/components/LanguageButtonGroup.svelte +++ /dev/null @@ -1,17 +0,0 @@ - - -
- - - -
diff --git a/src/components/Navbar.astro b/src/components/Navbar.astro index ebbfe3a..e1fab57 100644 --- a/src/components/Navbar.astro +++ b/src/components/Navbar.astro @@ -1,15 +1,14 @@ --- -import { localizePathname } from "@/utils/linking" -import { languageTag } from "@/paraglide/runtime" +import LocaleLink from "./links/LocaleLink.astro" import Links from "@/links" ---
{ Links.map(({ to, label }) => ( - - {label} - + + {label()} + )) }
diff --git a/src/components/links/LocaleLink.astro b/src/components/links/LocaleLink.astro new file mode 100644 index 0000000..e8e25af --- /dev/null +++ b/src/components/links/LocaleLink.astro @@ -0,0 +1,16 @@ +--- +import { languageTag, type AvailableLanguageTag } from "@/paraglide/runtime" +import { localizePathname, type NavLink } from "@/utils/linking" +import type { ComponentProps } from "@/types/props" + +interface Props extends ComponentProps { + to: NavLink + lang?: AvailableLanguageTag +} + +const { to, class: clazz, lang = languageTag() } = Astro.props +--- + + + + diff --git a/src/links.ts b/src/links.ts index 90df433..f716b76 100644 --- a/src/links.ts +++ b/src/links.ts @@ -1,22 +1,31 @@ -import * as m from "./paraglide/messages.js" +import * as m from "@/paraglide/messages.js" +import type { NavLink } from "@/utils/linking.ts" interface Link { - label: string - to: `/${string}` + label: () => string + to: NavLink } const Links: Link[] = [ { - label: m.home(), + label: m.home, to: "/" }, { - label: m.myProjects(), - to: "/project" + label: m.myProjects, + to: "/projects" }, { - label: m.contactMe(), - to: "/contact-me" + label: m.myLinks, + to: "/links" + }, + { + label: m.hardware, + to: "/hardware" + }, + { + label: m.contactMe, + to: "/contact" } ] diff --git a/src/pages/contact-me.astro b/src/pages/contact.astro similarity index 100% rename from src/pages/contact-me.astro rename to src/pages/contact.astro diff --git a/src/pages/en/contact-me.astro b/src/pages/en/contact.astro similarity index 100% rename from src/pages/en/contact-me.astro rename to src/pages/en/contact.astro diff --git a/src/pages/en/project/[project].astro b/src/pages/en/projects/[project].astro similarity index 92% rename from src/pages/en/project/[project].astro rename to src/pages/en/projects/[project].astro index 908cfbe..3603e45 100644 --- a/src/pages/en/project/[project].astro +++ b/src/pages/en/projects/[project].astro @@ -2,6 +2,8 @@ import ProjectPage from "../../../components/projects/ProjectPage.astro" import { type GetStaticPathsResult } from "astro" +export const prerender = true + export function getStaticPaths(): GetStaticPathsResult { return [ { params: { project: "hotelservice" } }, diff --git a/src/pages/en/project/index.astro b/src/pages/en/projects/index.astro similarity index 100% rename from src/pages/en/project/index.astro rename to src/pages/en/projects/index.astro diff --git a/src/pages/project/[project].astro b/src/pages/projects/[project].astro similarity index 92% rename from src/pages/project/[project].astro rename to src/pages/projects/[project].astro index 4e9d1cf..f5bbcd1 100644 --- a/src/pages/project/[project].astro +++ b/src/pages/projects/[project].astro @@ -2,6 +2,8 @@ import ProjectPage from "../../components/projects/ProjectPage.astro" import { type GetStaticPathsResult } from "astro" +export const prerender = true + export function getStaticPaths(): GetStaticPathsResult { return [ { params: { project: "hotelservice" } }, diff --git a/src/pages/project/index.astro b/src/pages/projects/index.astro similarity index 100% rename from src/pages/project/index.astro rename to src/pages/projects/index.astro diff --git a/src/types/types.ts b/src/types/types.ts new file mode 100644 index 0000000..a738bb4 --- /dev/null +++ b/src/types/types.ts @@ -0,0 +1 @@ +export type AbsolutePathname = `/${string}` diff --git a/src/utils/linking.ts b/src/utils/linking.ts index e4327e2..3105a7a 100644 --- a/src/utils/linking.ts +++ b/src/utils/linking.ts @@ -1,20 +1,38 @@ import type { AvailableLanguageTag } from "@/paraglide/runtime.js" +import type { AbsolutePathname } from "@/types/types.ts" -type AbsolutePathname = `/${string}` +interface TranslatedPathnames { + nb: AbsolutePathname + en: `/en${string}` +} -// TODO what? -// https://inlang.com/m/iljlwzfs/paraglide-astro-i18n -const pathnames: Record -> = { - "/contact-me": { - nb: "/contact-me", - en: "/en/contact-me" +export type NavLink = "/" | "/contact" | "/projects" | "/links" | "/hardware" + +const paths: NavLink[] = [ + "/", + "/contact", + "/projects", + "/links", + "/hardware" +] + +/** + * Defines the localized pathnames for the site. + * The key must be used to navigate to the correct path. + * The value is the path that will be used for the given locale. + * + * @see https://inlang.com/m/iljlwzfs/paraglide-astro-i18n + */ +const pathnames: Record = {} +for (const path of paths) { + pathnames[path] = { + nb: path, + en: `/en${path}` } } export function localizePathname( - pathname: AbsolutePathname, + pathname: NavLink, locale: AvailableLanguageTag ) { if (pathnames[pathname]) { @@ -22,3 +40,10 @@ export function localizePathname( } return pathname } + +export function resolvePathname(pathname: string): AbsolutePathname { + if (pathname.startsWith("/en")) { + return pathname.slice(3) as AbsolutePathname + } + return pathname as AbsolutePathname +}