From 2f3476f46ec7322408cb2c6dacf8b9f3910017ee Mon Sep 17 00:00:00 2001 From: Kristin Fritsch Date: Sat, 19 Jul 2025 15:30:05 +0200 Subject: [PATCH 01/17] Convert website to static GitHub Pages deployment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove German language support, keep only English - Configure Next.js for static export with GitHub Pages basePath support - Add asset path utility function for proper GitHub Pages URL handling - Update all hardcoded asset paths to use dynamic basePath - Fix font URLs to work with GitHub Pages - Add .nojekyll file to prevent GitHub Pages from ignoring _next files - Update package.json with export script - Remove German translation files and city data - Format code with prettier 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .gitignore | 2 ++ data/cities/de/berlin.md | 21 ----------------- data/cities/de/jerusalem.md | 7 ------ data/cities/de/leipzig.md | 45 ------------------------------------- data/cities/de/zurich.md | 33 --------------------------- hooks/useTranslation.ts | 4 ---- next.config.js | 20 +++++++++++++++++ package.json | 1 + pages/_error.js | 7 +++++- pages/about.tsx | 6 +++-- pages/community.tsx | 4 +++- pages/contribute.tsx | 8 ++++--- pages/guides.tsx | 14 ++++++++---- pages/index.tsx | 16 ++++++++----- public/.nojekyll | 0 style/style-global.js | 6 ++--- translations/de.json | 1 - utils/assetPath.js | 19 ++++++++++++++++ 18 files changed, 84 insertions(+), 130 deletions(-) delete mode 100644 data/cities/de/berlin.md delete mode 100644 data/cities/de/jerusalem.md delete mode 100644 data/cities/de/leipzig.md delete mode 100644 data/cities/de/zurich.md create mode 100644 public/.nojekyll delete mode 100644 translations/de.json create mode 100644 utils/assetPath.js diff --git a/.gitignore b/.gitignore index 772db81..48125e6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,10 @@ node_modules src/.next .env src/out/ +out/ .DS_Store npm-debug.log next-env.d.ts .next .vercel +.claude/ diff --git a/data/cities/de/berlin.md b/data/cities/de/berlin.md deleted file mode 100644 index 978e5ae..0000000 --- a/data/cities/de/berlin.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -slug: berlin -title: Berlin -location: 'Berlin, Germany' -tagline: 'Where everything started... and you can take a ride in a rotating TV tower' -twitter: OTS_BLN -meetup_name: opentechschool-berlin -socials: - - twitter: https://twitter.com/ots_bln - - facebook: https://www.facebook.com/opentechschool.berlin -discourse_group: TeamBerlin ---- - -## About - -We are the group of people who created the first chapter of OpenTechSchool and -want you to start one in your own city! The venue that supported us from the -very beginning and where we host our events is the fantastic coworking space, -[co.up]. - -[co.up]: https://co-up.de/ diff --git a/data/cities/de/jerusalem.md b/data/cities/de/jerusalem.md deleted file mode 100644 index 113de9e..0000000 --- a/data/cities/de/jerusalem.md +++ /dev/null @@ -1,7 +0,0 @@ ---- - -slug: jerusalem -title: Jerusalem -location: 'Jerusalem, Israel' -is_inactive: true -meetup_name: 'opentechschool-jerusalem' diff --git a/data/cities/de/leipzig.md b/data/cities/de/leipzig.md deleted file mode 100644 index fc9d9be..0000000 --- a/data/cities/de/leipzig.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -slug: leipzig -title: Leipzig -location: Leipzig, Germany -tagline: Your beginners friendly tech community in Leipzig -credits: Thanks to Christian Doeller (www.christiandoeller.de) -meetup_name: opentechschool-leipzig -twitter: ots_le -socials: - - twitter: https://twitter.com/ots_le - - github: http://github.com/opentechschool-leipzig - - facebook: http://facebook.com/opentechschool.leipzig - - instagram: https://www.instagram.com/opentechschool_leipzig/ -members: - - christina: Christina - - krissi: Krissi - - norma: Norma ---- - -Wir sind eine Gruppe technikbegeisterter Menschen die sich regelmäßig trifft um an Projekten zu arbeiten, Technologien zu diskutieren und sich austauscht und unterstützt. - -Wir organisieren Veranstaltungen zum Lernen, Zusammenzuarbeiten und um andere Lernende zu treffen. Wenn du Dich für Technik interessierst, du programmieren lernen möchtest oder wenn du Unterstützung bei deinem Projekt brauchst, dann ist die OTS Community genau das Richtige für dich. - -## Unser Meetup - -Wir treffen uns regelmäßig Montag oder Donnerstag zwischen 19 und 22 Uhr im Basislager um gemeinsam zu lernen, uns bei der Arbeit an Projekten zu unterstützen oder gegenseitig zu motivieren. - -Die Veranstaltung ist kostenlos und jeder ist herzlich eingeladen teilzunehmen. Wir bieten keine fortlaufenden Programmierworkshops an, aber wir treffen uns um deine Fragen zu beantworten und dich beim Lernen zu unterstützen. Die Teilnehmer unseres Meetups haben unterschiedliche Erfahrungsbereiche und helfen dir gerne weiter. - -Bitte lies unseren [Code of Conduct](/code-of-conduct/) bevor du vorbei kommst. - -Vielen Dank auch an das [Basislager](https://www.basislager.co) für die Bereitstellung der Räumlichkeiten. - -## Lernressourcen - -Eine Sammlung an Lernressourcen findest du [hier](https://github.com/OpenTechSchool-Leipzig/learning-resources). Gerne kannst du dein Lieblingstutorial hinzufügen. - -## Projekte - -Wir haben eine Reihe an Projekten die wir betreuen und bei denen du dich gern beteiligen kannst. -Um mehr zu Erfahren, schaue auf unseren [Github Seite](http://github.com/opentechschool-leipzig) oder sprich uns direkt an. - -## Kontakt - -Hast du noch Fragen, dann sende uns eine [E-Mail](mailto:leipzig@opentechschool.org) or melde dich in unserem [Slack](https://join.slack.com/t/opentechschool/shared_invite/zt-1mpx31hk2-C0~bk3sXUhzyT57f8J4Smg) (channel: #leipzig). diff --git a/data/cities/de/zurich.md b/data/cities/de/zurich.md deleted file mode 100644 index 5d87935..0000000 --- a/data/cities/de/zurich.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -slug: zurich -title: Zürich -location: 'Zürich, Switzerland' -tagline: 'Deine anfängerfreundliche Tech-Community in Zürich' -meetup_name: opentechschool-zurich -socials: - - github: https://github.com/opentechschool-zurich/ - - matrix: #ots-zh:matrix.org -members: - - ale: Ale Rimoldi ---- - -Wir sind eine Gruppe technikbegeisterter Menschen, die sich regelmässig trifft um an Projekten zu arbeiten, Technologien zu diskutieren, untereinander auszutauschen und gegenseitig zu unterstützen. - -Wir organisieren Veranstaltungen zum Lernen, Zusammenzuarbeiten oder einfach um andere Lernende zu treffen. Wenn du dich für Technik interessierst, programmieren lernen möchtest oder wenn Unterstützung bei deinem Projekt brauchst, dann ist die OpenTechSchool Community genau das Richtige für dich. - -## Unser Co-Learning Treffen - -Wir treffen jeden Dienstag von 19.00 bis 21.00 Uhr in der [Liip Arena] (https://www.openstreetmap.org/node/721046233), um gemeinsam zu lernen, weiterzubilden und gegenseitig zu motivieren. Teilnehmer beginnen mit der Programmierung, lernen neue Skills oder arbeiten an eigenen Projekten. - -In den Wintermonaten treffen wir auch am Sonntag Abend von 17:30 bis 19:30 Uhr. - -Die Veranstaltung ist kostenlos und jeder ist herzlich willkommen. Wir bieten keine regelmässigen Programmier-Workshops an, aber bei unsere Treffen werden Programmierporblemen besprochen und alle möglichen Fragen gestellt, die beim Einstieg in die Programmierung auftauchen können. Die Teilnehmer, haben unterschiedliche Erfahrungsbereiche und Niveaus und helfen dir gerne weiter. - -Bitte lies unseren [Code of Conduct](/code-of-conduct/) bevor du vorbei kommst. - -Herzlichen Dank an [Liip](https://liip.ch) für die Bereitstellung der Räumlichkeiten. - - -## Kontakt - -Hast du noch Fragen, dann schicke uns eine [E-Mail](mailto:team.zurich@opentechschool.org) or melde dich in unserem [Matrix / Element](https://matrix.to/#/#ots-zh:matrix.org) (Channel: #ots-zh:matrix.org / opentechschool-zurich). diff --git a/hooks/useTranslation.ts b/hooks/useTranslation.ts index a5bc820..9470cd3 100644 --- a/hooks/useTranslation.ts +++ b/hooks/useTranslation.ts @@ -9,12 +9,8 @@ export default function useTranslation() { let strings const ENstrings: Strings = require('../translations/en.json') - const DEstrings: Strings = require('../translations/de.json') switch (locale) { - // case 'de': - // strings = DEstrings - // break default: strings = ENstrings } diff --git a/next.config.js b/next.config.js index 8a53767..a699289 100644 --- a/next.config.js +++ b/next.config.js @@ -1,6 +1,26 @@ const path = require('path') +const isGithubActions = process.env.GITHUB_ACTIONS || false + +let assetPrefix = '' +let basePath = '' + +if (isGithubActions) { + const repo = process.env.GITHUB_REPOSITORY.replace(/.*?\//, '') + assetPrefix = `/${repo}/` + basePath = `/${repo}` +} + module.exports = { + ...(assetPrefix && { assetPrefix }), + ...(basePath && { basePath }), + trailingSlash: true, + eslint: { + ignoreDuringBuilds: true, + }, + images: { + unoptimized: true, + }, webpack: function(config) { config.module.rules.push({ test: /\.md$/, diff --git a/package.json b/package.json index 306aff0..7c76f87 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "open": "sleepms 5000 && open http://localhost:3000", "dev": "npm run clean-cache && npm run lint && concurrently \"npm run lint:watch\" next \"npm run open\" --names \"🛂,🏗️,🖥️\" --prefix name ", "build": "npm run clean-cache && next build", + "export": "npm run clean-cache && next build", "test": "echo \"Error: no test specified\" && exit 1" }, "husky": { diff --git a/pages/_error.js b/pages/_error.js index 2fbca33..6f0d1cf 100644 --- a/pages/_error.js +++ b/pages/_error.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types' import PageLayout from '../components/PageLayout/PageLayout' import useTranslation from '../hooks/useTranslation' import WithLocale from '../containers/withLocale' +import { getAssetPath } from '../utils/assetPath' function ErrorPage({ errorCode }) { const { t } = useTranslation() @@ -16,7 +17,11 @@ function ErrorPage({ errorCode }) { {t('404.description')}
{t('404.description2')} - lost + lost - - ) - default: - return ( - - -
{t('500.description')}
-
- ) - } + return ( + +
+ {t('404.description')} +
+ {t('404.description2')} + lost +
+ +
+ ) } -ErrorPage.getInitialProps = ({ res, err }) => { - const errorCode = res ? res.statusCode : err ? err.statusCode : 404 - return { errorCode } -} - -ErrorPage.propTypes = { - errorCode: PropTypes.number.isRequired, -} +ErrorPage.propTypes = {} export default WithLocale(ErrorPage) diff --git a/pages/cities/[slug].js b/pages/cities/[slug].js index 92f2ca7..2e03bf7 100644 --- a/pages/cities/[slug].js +++ b/pages/cities/[slug].js @@ -200,16 +200,38 @@ export function CityTemplate({ content, data }) { ) } -CityTemplate.getInitialProps = async (ctx) => { - const { lang = 'en', slug } = ctx.query +export async function getStaticPaths() { + const fs = require('fs') + const path = require('path') + + const citiesDir = path.join(process.cwd(), 'data/cities/en') + const filenames = fs.readdirSync(citiesDir) + + const paths = filenames.map((name) => ({ + params: { + slug: name.replace(/\.md$/, ''), + }, + })) + + return { + paths, + fallback: false, + } +} + +export async function getStaticProps({ params }) { + const { slug } = params + const lang = 'en' // Since we removed multi-language support const content = await import(`../../data/cities/${lang}/${slug}.md`) // gray-matter parses the yaml frontmatter from the md body const data = matter(content.default) return { - content, - ...data, + props: { + content: data.content, + data: data.data, + }, } } From 565ed23976bc8fb3cd6e192b9a7bddea7fcf8570 Mon Sep 17 00:00:00 2001 From: Kristin Fritsch Date: Sat, 19 Jul 2025 16:20:37 +0200 Subject: [PATCH 09/17] Fix hardcoded image paths for GitHub Pages deployment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update all remaining hardcoded asset paths to use assetPath utility for proper GitHub Pages basePath support: - CityHero component background images - Meta component favicons and manifest links - MarkdownTeam component member images - Cities page social icons and about images 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- components/CityHero/CityHero.tsx | 4 +++- components/Meta.tsx | 14 ++++++++------ components/Team/MarkdownTeam.tsx | 4 +++- pages/cities/[slug].js | 26 ++++++++++++++------------ 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/components/CityHero/CityHero.tsx b/components/CityHero/CityHero.tsx index 87a117a..a1e1216 100644 --- a/components/CityHero/CityHero.tsx +++ b/components/CityHero/CityHero.tsx @@ -6,9 +6,11 @@ import { mediaquery } from '../../style/style' // import Link from 'next/link' // import OutlineButton from '../Button/OutlineButton' import useTranslation from '../../hooks/useTranslation' +import { useAssetPath } from '../../utils/assetPath' function CityHero({ cityName, title, tagline, meetupName, credits }) { const { t } = useTranslation() + const assetPath = useAssetPath() const [members, setMembers] = useState() useEffect(() => { @@ -30,7 +32,7 @@ function CityHero({ cityName, title, tagline, meetupName, credits }) { return (
-
+

{title}

"{tagline}" diff --git a/components/Meta.tsx b/components/Meta.tsx index 6fa7a93..f3fca4e 100644 --- a/components/Meta.tsx +++ b/components/Meta.tsx @@ -1,9 +1,11 @@ import PropTypes from 'prop-types' import Head from 'next/head' import useTranslation from '../hooks/useTranslation' +import { useAssetPath } from '../utils/assetPath' export default function Meta({ pageTitle, pageDescription, pageImage }) { const { t } = useTranslation() + const assetPath = useAssetPath() pageTitle = `${pageTitle} | OpenTechSchool` return ( <> @@ -22,7 +24,7 @@ export default function Meta({ pageTitle, pageDescription, pageImage }) { @@ -30,22 +32,22 @@ export default function Meta({ pageTitle, pageDescription, pageImage }) { - + - + ) diff --git a/components/Team/MarkdownTeam.tsx b/components/Team/MarkdownTeam.tsx index 7a3fe92..611e527 100644 --- a/components/Team/MarkdownTeam.tsx +++ b/components/Team/MarkdownTeam.tsx @@ -1,5 +1,6 @@ import PropTypes from 'prop-types' import Grid from '@material-ui/core/Grid' +import { useAssetPath } from '../../utils/assetPath' function chunkArray(array, size) { const chunkedArray = [] @@ -12,6 +13,7 @@ function chunkArray(array, size) { } const TeamSection = ({ members }) => { + const assetPath = useAssetPath() const chunksOfFour = chunkArray(members, 4) return ( @@ -35,7 +37,7 @@ const TeamSection = ({ members }) => { key={key} item > - +

{Object.values(member)}

) diff --git a/pages/cities/[slug].js b/pages/cities/[slug].js index 2e03bf7..587f932 100644 --- a/pages/cities/[slug].js +++ b/pages/cities/[slug].js @@ -18,26 +18,28 @@ import TextSection from '../../components/Section/TextSection' import TeamSection from '../../components/Section/TeamSection' import TwitterFeed from '../../components/TwitterFeed' import Events from '../../components/Events' - -const socialIconsList = { - facebook: , - twitter: , - github: , - instagram: , - discourse: { imgSrc: '/discourse_blue_icon.png' }, - matrix: { imgSrc: '/matrix_logo.png' }, -} +import { useAssetPath } from '../../utils/assetPath' const WrappedIcon = (props) => WrappedIcon.muiName = 'Icon' export function CityTemplate({ content, data }) { const { t } = useTranslation() + const assetPath = useAssetPath() const markdownBody = content const frontmatter = data const cityName = `${frontmatter.slug}`.toLowerCase() const meetupName = frontmatter.meetup_name + const socialIconsList = { + facebook: , + twitter: , + github: , + instagram: , + discourse: { imgSrc: assetPath('/discourse_blue_icon.png') }, + matrix: { imgSrc: assetPath('/matrix_logo.png') }, + } + const [events, setEvents] = useState({}) const [hasEvents, setHasEvents] = useState(false) const [showMoreLink, setShowMoreLink] = useState(true) @@ -136,7 +138,7 @@ export function CityTemplate({ content, data }) {
- + {frontmatter.credits && (

Credits: {frontmatter.credits}

)} @@ -203,10 +205,10 @@ export function CityTemplate({ content, data }) { export async function getStaticPaths() { const fs = require('fs') const path = require('path') - + const citiesDir = path.join(process.cwd(), 'data/cities/en') const filenames = fs.readdirSync(citiesDir) - + const paths = filenames.map((name) => ({ params: { slug: name.replace(/\.md$/, ''), From 084798e477ad8f46c5e414d68563e2dd5688d3d0 Mon Sep 17 00:00:00 2001 From: Kristin Fritsch Date: Sat, 19 Jul 2025 16:25:47 +0200 Subject: [PATCH 10/17] Fix font paths for GitHub Pages basePath support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update global CSS font declarations to use dynamic basePath for GitHub Pages deployment: - Add environment detection for GitHub Actions - Use GITHUB_REPOSITORY to extract repository name for basePath - Apply basePath to OpenSans, Roboto, and Material Icons font URLs - Ensures fonts load correctly when deployed with basePath on GitHub Pages 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- style/style-global.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/style/style-global.js b/style/style-global.js index 9c547b5..fa1bdef 100644 --- a/style/style-global.js +++ b/style/style-global.js @@ -1,6 +1,9 @@ import css from 'styled-jsx/css' import { mediaquery } from './style.js' +const isGithubActions = process.env.GITHUB_ACTIONS || false +const basePath = isGithubActions ? `/${process.env.GITHUB_REPOSITORY?.replace(/.*?\//, '') || ''}` : '' + export default css.global` :root { /* COLORS */ @@ -21,21 +24,21 @@ export default css.global` font-family: 'Open Sans'; font-stretch: 100%; font-display: swap; - src: url('/fonts/OpenSans/OpenSans.woff2') format('woff2'); + src: url('${basePath}/fonts/OpenSans/OpenSans.woff2') format('woff2'); } @font-face { font-family: 'Roboto'; font-stretch: 100%; font-display: swap; - src: url('/fonts/Roboto/Roboto.woff2') format('woff2'); + src: url('${basePath}/fonts/Roboto/Roboto.woff2') format('woff2'); } @font-face { font-family: 'Material Icons'; font-style: normal; font-weight: 400; - src: url('/fonts/MaterialIcons/MaterialIcons.woff2') format('woff2'); + src: url('${basePath}/fonts/MaterialIcons/MaterialIcons.woff2') format('woff2'); } .material-icons { From 6106732c6879946ca4dd55326978f83e3b25ee8c Mon Sep 17 00:00:00 2001 From: Kristin Fritsch Date: Sat, 19 Jul 2025 16:26:42 +0200 Subject: [PATCH 11/17] Update README with GitHub Pages deployment instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace outdated Zeit.co deployment information - Add detailed instructions for building with GitHub Pages basePath locally - Include environment variables needed for proper GitHub Pages build - Explain difference between local and GitHub Pages builds - Document asset path behavior with basePath configuration 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- README.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8ea463b..ba8eaa1 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,34 @@ Yet, we avoid using javascript-in-css as much as possible therefore it will be e ## Deployment -This website is being deployed to [Zeit.co](https://zeit.co/) on the free team account https://zeit.co/opentechschool. Every push to master goes live automatically via their Github integration. +This website is deployed to GitHub Pages. Every push to the `github-pages-new` branch automatically triggers the GitHub Actions workflow that builds and deploys the static site. + +### Building for GitHub Pages Locally + +To test the GitHub Pages build locally with the correct basePath configuration: + +```bash +# Build and export with GitHub Pages environment variables +GITHUB_ACTIONS=true GITHUB_REPOSITORY=OpenTechSchool/websitenext npm run build +GITHUB_ACTIONS=true GITHUB_REPOSITORY=OpenTechSchool/websitenext npx next export + +# The static files will be generated in the 'out' directory +# All asset paths (images, fonts, links) will include the /websitenext basePath +``` + +**Important:** When building for GitHub Pages, the build process: + +- Adds `/websitenext` basePath to all asset URLs +- Configures static export for proper GitHub Pages deployment +- Ensures fonts, images, and internal links work correctly with the repository's subpath + +For local development without basePath, use the standard commands: + +```bash +npm run dev # Development server +npm run build # Production build (local) +npm run export # Static export (local) +``` ## Contact From 827dba97c22277ec04d4ce0c9beda389417ac497 Mon Sep 17 00:00:00 2001 From: Kristin Fritsch Date: Sat, 19 Jul 2025 16:31:14 +0200 Subject: [PATCH 12/17] Remove Slack references from README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove Slack channel mentions from contribution guidelines - Replace Slack communication with GitHub issue discussions - Encourage using GitHub issues for help and collaboration - Simplify communication channels to focus on GitHub-based workflow 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- README.md | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index ba8eaa1..d7446ff 100644 --- a/README.md +++ b/README.md @@ -25,11 +25,11 @@ If you want to contribute but don't know on what to work on, check our github is If you are beginner, search for the label `good first issues`.
Assign the issue to your self and when you are done, make a PR to review.
-Always feel free to reach out for help. You can write in the issue it self, you can open a PR as draft and ask suggestion about your code or you can contact us on [slack](https://opentechschool-slack.herokuapp.com) in the #website-dev channel. +Always feel free to reach out for help. You can write in the issue itself, you can open a PR as draft and ask suggestion about your code. -### Requisit: +### Requirements: -`Node version > 9` +`Node version >= 12` (recommended: Node 18+ or 20+) `npm` @@ -71,9 +71,8 @@ WrappedIcon.muiName = Icon.muiName; ## Cities data -Markdown for city can be found in data/cities.
-Inside this folder you will find subfolders based on language. Each city must have at least english language to be visible.
-Add as many language as you wish for your city. The files must have always the same name: `city-name.md`.
+Markdown for city can be found in `data/cities/en/`.
+Each city file should be named `city-name.md` and placed in the English directory.
If you want to add a city that is currently inactive, just add `is_inactive` to the markdown. Each city **MUST HAVE**: @@ -116,26 +115,21 @@ members: ### Translation -Translation are located in `translations/`. Here there are some configuration and typescript file needed to make translation works but most important there are `json` files for each language.
-Those are translation for all the website except the city page.
-If you create new content, please remember to add your text to those files, at least to the english translation. +Translations are located in `translations/` directory. The website currently supports English only after the conversion to static site generation.
+If you create new content, please remember to add your text to the `en.json` translation file. -If you add a new language add a `yourLanguage.json` file in the `translations/` directory and remember to add your language to the `config.ts` files to make it available to the `` +To use translations in a component, use the `t()` function from the `useTranslation` hook: -If you want to use translation in a file, you can use the `t()` function, which it takes as a argument the string to translate from the language jons file.
-Example: -In my `en.json` i have such string: +```javascript +import useTranslation from '../hooks/useTranslation' -``` -"about": { - "title": "About OTS" +const MyComponent = () => { + const { t } = useTranslation() + return

{t('about.title')}

} ``` -in my `about.tsx` page i can use the `t` function like that: `t('about.title')`. -`t()` function always fall back to english. If the translation doesn't exists even in the `en.json` file, you will see printed the string of your translation (i.e. `about.title`) and a warning will show up in your console. - -`t()` function can be extracted form the `useTranslation` hook and in order to be effective in a page, the page must be wrapped with the `WithLocale()` HOC. +The `t()` function takes a key from the `en.json` file and falls back to displaying the key if translation is missing. ### Conventions @@ -188,4 +182,4 @@ Feel free to open a new issue here on github. Try to label it as best as you can Have an idea and already know how to develop it? Go ahead and make a PR, we are very happy to review it. Have an idea but would like to talk to someone to know how to better proceed? -Join us on [slack](https://opentechschool-slack.herokuapp.com): channel #website-dev +Feel free to open a GitHub issue to discuss your ideas and get guidance on implementation. From a5d1ad8a2b12762f39ab4976ea915929c335c2ef Mon Sep 17 00:00:00 2001 From: Kristin Fritsch Date: Sat, 19 Jul 2025 16:51:12 +0200 Subject: [PATCH 13/17] Fix client-side navigation font loading issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add font preloading to _document.tsx to ensure fonts are cached during initial page load, preventing FOUT during client-side navigation. The preload links use environment-aware basePath detection for proper GitHub Pages deployment. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- pages/_document.tsx | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/pages/_document.tsx b/pages/_document.tsx index 8b8ece8..e079f71 100644 --- a/pages/_document.tsx +++ b/pages/_document.tsx @@ -3,9 +3,35 @@ import Document, { Html, Head, Main, NextScript } from 'next/document' export default class MyDocument extends Document { render() { + const isGithubActions = process.env.GITHUB_ACTIONS || false + const basePath = isGithubActions ? `/${process.env.GITHUB_REPOSITORY?.replace(/.*?\//, '') || ''}` : '' + return ( - + + {/* Preload fonts for better client-side navigation */} + + + +
From 95e784c8b64415bfb112ab746f78294ed03da458 Mon Sep 17 00:00:00 2001 From: Kristin Fritsch Date: Sat, 19 Jul 2025 17:08:08 +0200 Subject: [PATCH 14/17] Update branch in deploy config --- .github/workflows/deploy-github-pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-github-pages.yml b/.github/workflows/deploy-github-pages.yml index abf45b5..9f16e29 100644 --- a/.github/workflows/deploy-github-pages.yml +++ b/.github/workflows/deploy-github-pages.yml @@ -5,7 +5,7 @@ on: branches: - master - main - - github-pages-new + - github-pages workflow_dispatch: permissions: From ecea8393b847ff55083d713390831fa09077a6ae Mon Sep 17 00:00:00 2001 From: Kristin Fritsch Date: Sat, 19 Jul 2025 18:16:28 +0200 Subject: [PATCH 15/17] Make build-time env vars available during runtime --- next.config.js | 3 +++ style/style-global.js | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/next.config.js b/next.config.js index a699289..b565d25 100644 --- a/next.config.js +++ b/next.config.js @@ -33,5 +33,8 @@ module.exports = { external: { MEETUP_URL: 'http://meetup.com', }, + // Make build-time environment variables available at runtime + NEXT_PUBLIC_GITHUB_ACTIONS: process.env.GITHUB_ACTIONS || 'false', + NEXT_PUBLIC_GITHUB_REPOSITORY: process.env.GITHUB_REPOSITORY || '', }, } diff --git a/style/style-global.js b/style/style-global.js index fa1bdef..8c869fb 100644 --- a/style/style-global.js +++ b/style/style-global.js @@ -1,8 +1,8 @@ import css from 'styled-jsx/css' import { mediaquery } from './style.js' -const isGithubActions = process.env.GITHUB_ACTIONS || false -const basePath = isGithubActions ? `/${process.env.GITHUB_REPOSITORY?.replace(/.*?\//, '') || ''}` : '' +const isGithubActions = process.env.NEXT_PUBLIC_GITHUB_ACTIONS || false +const basePath = isGithubActions ? `/${process.env.NEXT_PUBLIC_GITHUB_REPOSITORY?.replace(/.*?\//, '') || ''}` : '' export default css.global` :root { From d4a3971cfb2d9ae56927ac9f7a92d1f26899eed9 Mon Sep 17 00:00:00 2001 From: Kristin Fritsch Date: Sat, 19 Jul 2025 18:42:21 +0200 Subject: [PATCH 16/17] Make custom domain configurable in deploy config --- .github/workflows/deploy-github-pages.yml | 2 ++ README.md | 12 +++++++++--- next.config.js | 4 +++- pages/_document.tsx | 3 ++- style/style-global.js | 3 ++- 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy-github-pages.yml b/.github/workflows/deploy-github-pages.yml index 9f16e29..9fa0ebf 100644 --- a/.github/workflows/deploy-github-pages.yml +++ b/.github/workflows/deploy-github-pages.yml @@ -38,6 +38,8 @@ jobs: env: GITHUB_ACTIONS: true GITHUB_REPOSITORY: ${{ github.repository }} + # Set CUSTOM_DOMAIN=true when using custom domain (e.g., opentechschool.org) + # CUSTOM_DOMAIN: true - name: Upload artifact uses: actions/upload-pages-artifact@v3 diff --git a/README.md b/README.md index d7446ff..c9d662d 100644 --- a/README.md +++ b/README.md @@ -151,13 +151,15 @@ This website is deployed to GitHub Pages. Every push to the `github-pages-new` b To test the GitHub Pages build locally with the correct basePath configuration: +Note: We are using `out` instead of `websitenext`, but the github action will copy files from `out` to `websitenext` + ```bash # Build and export with GitHub Pages environment variables -GITHUB_ACTIONS=true GITHUB_REPOSITORY=OpenTechSchool/websitenext npm run build -GITHUB_ACTIONS=true GITHUB_REPOSITORY=OpenTechSchool/websitenext npx next export +GITHUB_ACTIONS=true GITHUB_REPOSITORY=OpenTechSchool/out npm run build +GITHUB_ACTIONS=true GITHUB_REPOSITORY=OpenTechSchool/out npx next export # The static files will be generated in the 'out' directory -# All asset paths (images, fonts, links) will include the /websitenext basePath +# All asset paths (images, fonts, links) will include the /out basePath ``` **Important:** When building for GitHub Pages, the build process: @@ -174,6 +176,10 @@ npm run build # Production build (local) npm run export # Static export (local) ``` +### Using a custom domain + +Set `CUSTOM_DOMAIN` to true in `deploy-github-pages.yml` when using a custom domain e.g. opentechschool.org + ## Contact Found an issue, a bug or have an idea for a great new feature? diff --git a/next.config.js b/next.config.js index b565d25..ac0ef3c 100644 --- a/next.config.js +++ b/next.config.js @@ -1,11 +1,12 @@ const path = require('path') const isGithubActions = process.env.GITHUB_ACTIONS || false +const hasCustomDomain = process.env.CUSTOM_DOMAIN === 'true' let assetPrefix = '' let basePath = '' -if (isGithubActions) { +if (isGithubActions && !hasCustomDomain) { const repo = process.env.GITHUB_REPOSITORY.replace(/.*?\//, '') assetPrefix = `/${repo}/` basePath = `/${repo}` @@ -36,5 +37,6 @@ module.exports = { // Make build-time environment variables available at runtime NEXT_PUBLIC_GITHUB_ACTIONS: process.env.GITHUB_ACTIONS || 'false', NEXT_PUBLIC_GITHUB_REPOSITORY: process.env.GITHUB_REPOSITORY || '', + NEXT_PUBLIC_CUSTOM_DOMAIN: process.env.CUSTOM_DOMAIN || 'false', }, } diff --git a/pages/_document.tsx b/pages/_document.tsx index e079f71..4e0ba50 100644 --- a/pages/_document.tsx +++ b/pages/_document.tsx @@ -4,7 +4,8 @@ import Document, { Html, Head, Main, NextScript } from 'next/document' export default class MyDocument extends Document { render() { const isGithubActions = process.env.GITHUB_ACTIONS || false - const basePath = isGithubActions ? `/${process.env.GITHUB_REPOSITORY?.replace(/.*?\//, '') || ''}` : '' + const hasCustomDomain = process.env.CUSTOM_DOMAIN === 'true' + const basePath = (isGithubActions && !hasCustomDomain) ? `/${process.env.GITHUB_REPOSITORY?.replace(/.*?\//, '') || ''}` : '' return ( diff --git a/style/style-global.js b/style/style-global.js index 8c869fb..01edcd5 100644 --- a/style/style-global.js +++ b/style/style-global.js @@ -2,7 +2,8 @@ import css from 'styled-jsx/css' import { mediaquery } from './style.js' const isGithubActions = process.env.NEXT_PUBLIC_GITHUB_ACTIONS || false -const basePath = isGithubActions ? `/${process.env.NEXT_PUBLIC_GITHUB_REPOSITORY?.replace(/.*?\//, '') || ''}` : '' +const hasCustomDomain = process.env.NEXT_PUBLIC_CUSTOM_DOMAIN === 'true' +const basePath = (isGithubActions && !hasCustomDomain) ? `/${process.env.NEXT_PUBLIC_GITHUB_REPOSITORY?.replace(/.*?\//, '') || ''}` : '' export default css.global` :root { From f3cdfc8c0ae9ef6b97b3ad5906e823c342768eb6 Mon Sep 17 00:00:00 2001 From: Kristin Fritsch Date: Sat, 19 Jul 2025 18:46:58 +0200 Subject: [PATCH 17/17] Prepare for custom domain --- .github/workflows/deploy-github-pages.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/deploy-github-pages.yml b/.github/workflows/deploy-github-pages.yml index 9fa0ebf..fd96414 100644 --- a/.github/workflows/deploy-github-pages.yml +++ b/.github/workflows/deploy-github-pages.yml @@ -4,8 +4,6 @@ on: push: branches: - master - - main - - github-pages workflow_dispatch: permissions: @@ -39,7 +37,7 @@ jobs: GITHUB_ACTIONS: true GITHUB_REPOSITORY: ${{ github.repository }} # Set CUSTOM_DOMAIN=true when using custom domain (e.g., opentechschool.org) - # CUSTOM_DOMAIN: true + CUSTOM_DOMAIN: true - name: Upload artifact uses: actions/upload-pages-artifact@v3