| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Monorepo for CodeDay's web applications and shared packages.
| Path | Description |
|---|---|
| apps/www | Main CodeDay website (Next.js Pages Router) |
| packages/topo | Shared design system (Chakra UI components, theme, region detection) |
| packages/i18n | Shared internationalization (Paraglide JS messages + runtime) |
| packages/utils | Shared utilities (GraphQL fetch, debug, etc.) |
| packages/topocons | Icon library |
| packages/tsconfig | Shared TypeScript configuration |
pnpm install
pnpm run buildThe monorepo has two independent localization layers. Both are provided by shared packages so any app in the monorepo can use them.
| Layer | Purpose | Provided by | Example values |
|---|---|---|---|
| Locale (language) | UI string translations | packages/i18n | en, es |
| Region | Domain-specific data (phone numbers, emails, legal) | packages/topo (Region) | us, eu, uk, ca, in |
Translations are powered by Paraglide JS. Message files live in packages/i18n/messages/{locale}.json. Keys are prefixed by package — topo_* for design-system strings, www_* for app strings.
URL structure: Every page URL includes a locale prefix — /en/about, /es/about. If a user visits a bare path like /about, middleware detects the browser's preferred language and redirects.
import * as m from "@codeday/i18n/messages";
function Footer() {
return <p>{m.topo_footer_copyright({ currentYear: "2026" })}</p>;
}Client-side (React components):
import { getLocale } from "@codeday/i18n/runtime";
const locale = getLocale(); // "en" | "es"Server-side (getStaticProps / getServerSideProps):
import { getLocaleFromContext } from "@codeday/i18n/next-pages";
export const getStaticProps: GetStaticProps = async (ctx) => {
const locale = getLocaleFromContext(ctx);
// ...
};To use m.*() inside data-fetching functions, wrap with the locale helper:
import { withLocaleStaticProps } from "@codeday/i18n/next-pages";
import * as m from "@codeday/i18n/messages";
export const getStaticProps = withLocaleStaticProps(async (ctx) => {
return { props: { title: m.page_title() } };
});| Import path | Contents |
|---|---|
| @codeday/i18n/messages | Type-safe message functions (m.key()) |
| @codeday/i18n/runtime | getLocale(), setLocale(), overwriteGetLocale(), baseLocale, locales, Locale type |
| @codeday/i18n/next-pages | getLocaleFromContext(), withLocaleStaticProps(), withLocaleServerSideProps() |
Region codes are resolved from the top-level domain the visitor is using. This is independent of UI language — a user on codeday.fr gets region eu but can still view the site in English.
@codeday/topo/Region ships a built-in TLD_REGION_MAP:
| TLD | Region | TLD | Region | |
|---|---|---|---|---|
| .org | us | .ee | eu | |
| .us | us | .se | eu | |
| .ca | ca | .it | eu | |
| .co.uk | uk | .fr | eu | |
| .in | in | .es | eu | |
| .ch | eu | |||
| .be | eu |
Apps can pass an optional overrides map to add new TLDs or override specific full domain names.
import { getRegionFromHostname, REGION_HEADER } from "@codeday/topo/Region/config";
// inside middleware():
const region = getRegionFromHostname(request.headers.get("host"));
const headers = new Headers(request.headers);
headers.set(REGION_HEADER, region);
return NextResponse.next({ request: { headers } });import { RegionProvider, getRegionFromHostname } from "@codeday/topo/Region";
const region = useMemo(
() => getRegionFromHostname(typeof window !== "undefined" ? window.location.hostname : undefined),
[],
);
return <RegionProvider value={region}>...</RegionProvider>;Pass an overrides map to getRegionFromHostname. Full-domain keys take priority, then override TLD keys, then the built-in TLD_REGION_MAP.
const overrides = { "staging.codeday.org": "eu", "dev": "us" };
const region = getRegionFromHostname("staging.codeday.org", overrides); // "eu"Client-side (React components):
import { useRegion } from "@codeday/topo/Region";
const region = useRegion(); // "us" | "eu" | "uk" | ...Server-side (getServerSideProps):
import { getRegionFromContext } from "@codeday/topo/Region";
export const getServerSideProps: GetServerSideProps = async (ctx) => {
const region = getRegionFromContext(ctx);
return { props: { region } };
};getRegionFromContext only works with getServerSideProps (it reads request headers). In getStaticProps there is no request — use getRegionFromHostname() with a known hostname, or resolve the region client-side.
Add an entry to TLD_REGION_MAP in packages/topo/src/Region/config.ts. No other files need to change.
| Import path | Contents |
|---|---|
| @codeday/topo/Region/config | getRegionFromHostname(), TLD_REGION_MAP, DEFAULT_REGION, REGION_HEADER, RegionMap type — Edge-safe, no React |
| @codeday/topo/Region | Everything from config + RegionProvider, useRegion(), getRegionFromContext() |
| Back | FazBrowse Home | New Git URL |