Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
cd9ad58
✨ add translations to web app
antoinekm Dec 28, 2025
7296af9
📝 add translations conventions
antoinekm Dec 28, 2025
9cc8ad4
🌐 improve web app translations
antoinekm Dec 28, 2025
a4d48ec
📝 update translation imports for server components in claude.md
antoinekm Dec 28, 2025
b01a8dd
➕ add @radix-ui/react-dropdown-menu
antoinekm Dec 28, 2025
c1f670b
🌐 add link usage over all the web app
antoinekm Dec 28, 2025
3cb5f43
🌐 add home page translations
antoinekm Dec 28, 2025
fdd64c3
🌐 add npo page translations
antoinekm Dec 28, 2025
a47f780
🌐 add contact page translations
antoinekm Dec 28, 2025
dad8e5a
🌐 add legal pages translations
antoinekm Dec 28, 2025
a8d6a68
🌐 add careers pages translations
antoinekm Dec 28, 2025
585dfc7
🌐 add projects pages translations
antoinekm Dec 28, 2025
9418c88
🌐 fix capitalization of github in footer and localization files
antoinekm Dec 29, 2025
72a6e91
✏️ fix project link in navbar
antoinekm Dec 29, 2025
22ae53d
🌐 update canonical url generation to include locale prefix and set lo…
antoinekm Dec 29, 2025
8654804
🌐 improve locale handling in metadata functions and add hreflang support
antoinekm Dec 29, 2025
2e2d8ef
🔍 add project-team-schema and integrate team member data into project…
antoinekm Dec 29, 2025
adc533d
🩹 update project schema URL to use organization data constant
antoinekm Dec 29, 2025
7edf72e
🩹 update project schema url to use routes constant
antoinekm Dec 29, 2025
c81a194
🌐 add locale preference in cookies when using non-default locale prefix
antoinekm Dec 29, 2025
b47d2e5
🌐 improve locale priority handling in get-preferred-locale function
antoinekm Dec 29, 2025
946e776
🌐 improve pathname retrieval logic in get-pathname function
antoinekm Dec 29, 2025
0e9265e
🌐 update pathname handling to use slice method for locale prefix removal
antoinekm Dec 29, 2025
f21adb6
♻️ refactor organization url handling to use site config for consiste…
antoinekm Dec 29, 2025
06ddde5
🌐 fix typos in job details localization for improved clarity
antoinekm Dec 29, 2025
62cd294
🌐 fix typos in french localization for careers and projects pages
antoinekm Dec 29, 2025
4546bc9
🌐 update project metrics to include values for improved clarity and l…
antoinekm Dec 29, 2025
c6ba38e
🌐 update readme to clarify translation practices and avoid fallbacks …
antoinekm Dec 29, 2025
2882992
♻️ refactor site configuration to a dedicated file and update imports…
antoinekm Dec 29, 2025
b18a682
🌐 add translation for agency page metadata and add localization files
antoinekm Dec 29, 2025
4d7e50c
🌐 add translations for glossary page metadata in english and french
antoinekm Dec 29, 2025
004c8e3
🌐 add translations for "not found" metadata in english and french
antoinekm Dec 29, 2025
9700279
🌐 add english and french translations for agency portfolio metadata
antoinekm Dec 29, 2025
2a08c89
🌐 add translation for customer tag in english and french localization…
antoinekm Dec 29, 2025
64cc5c7
♻️ refactor hostname retrieval in project page component for improved…
antoinekm Dec 29, 2025
8ea3072
🌐 add translations for project status in english and french localizat…
antoinekm Dec 29, 2025
8233a0a
🌐 add translations support in metadata and og images
antoinekm Dec 29, 2025
f4986a9
📝 fix formatting in readme for translation files structure
antoinekm Dec 29, 2025
b8272be
🔧 update matcher regex in proxy configuration to exclude api routes
antoinekm Dec 29, 2025
e2f16bb
🔧 update proxy matcher regex to exclude api routes and file extensions
antoinekm Dec 29, 2025
5b575b4
🎨 update metadata import paths to use server-specific module
antoinekm Dec 29, 2025
3495653
🔒️ improve cookie security settings by adding http-only, secure, and …
antoinekm Dec 29, 2025
482ec06
🎨 improve glossary components with translations and improve content s…
antoinekm Dec 29, 2025
7796ea2
🌐 add translations for not-found metadata in agency pages
antoinekm Dec 29, 2025
7bcfe2f
🌐 add translations for services page metadata in english and french
antoinekm Dec 29, 2025
b2c4e83
♻️ replace next/link by @onruntime/translations/next
antoinekm Dec 29, 2025
bcf8e8c
🎨 update h2 to p for description in featured customer
antoinekm Dec 29, 2025
cecb368
🌐 add translations for agency city hero section in english and french
antoinekm Dec 29, 2025
efaefbe
♻️ refactor local portfolio project props to use is-primary instead o…
antoinekm Dec 29, 2025
a15394f
♻️ refactor get-tag-label function to use switch statement for improv…
antoinekm Dec 29, 2025
ea43c5c
🌐 add agencies translations
antoinekm Dec 30, 2025
5c72925
🎨 replace anchor tags with link component for improved navigation
antoinekm Dec 30, 2025
f023a0d
💄 update city-hero-section styles and add safelist for tailwind css c…
antoinekm Dec 30, 2025
516bc47
♻️ refactor agency primary-stat structure to remove value property fo…
antoinekm Dec 30, 2025
8685ac8
🌐 fix agency localization keys and update hero section structure
antoinekm Dec 30, 2025
752b994
🌐 remove contact-info sections from agency localization files for cle…
antoinekm Dec 30, 2025
42ce2fd
🌐 add services translations
antoinekm Dec 30, 2025
cad9e83
🌐 replace faq section with agency faq-section for improved agency-spe…
antoinekm Dec 30, 2025
7719a39
🎨 add mobile project link component and update navbar structure for i…
antoinekm Dec 30, 2025
9e79be7
✏️ fix french localization inconsistencies in service descriptions
antoinekm Dec 30, 2025
d39684c
♻️ refactor services page to directly use imported services and simpl…
antoinekm Dec 30, 2025
b932c8a
✨ add next-sitemap
antoinekm Dec 30, 2025
94b0075
✨ add changesets
antoinekm Dec 30, 2025
f61b2da
🩹 update robots.txt to use dynamic sitemap url from site configuration
antoinekm Dec 31, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
10 changes: 10 additions & 0 deletions .changeset/add-sitemap-options.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@onruntime/next-sitemap": minor
---

Add new configuration options for sitemap generation:

- `exclude`: Filter out routes using glob patterns or a function
- `priority`: Automatic depth-based priority calculation (or custom function)
- `changeFreq`: Set change frequency per route
- `additionalSitemaps`: Include custom sitemaps in the sitemap index
11 changes: 11 additions & 0 deletions .changeset/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "master",
"updateInternalDependencies": "patch",
"ignore": ["@onruntime/web"]
}
14 changes: 13 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ pnpm --filter @onruntime/web build

### Web App Structure (`apps/web/src/`)

- **app/**: Next.js App Router pages and API routes
- **app/**: Next.js App Router pages and API routes (under `[locale]/`)
- **components/**: React components (ui/, layout/, marketing/)
- **services/**: External API clients with lazy initialization
- **constants/**: Static data (projects, agencies, services, team members)
- **content/**: MDX content (glossary, legal pages)
- **lib/**: Utilities and helpers
- **locales/**: Translation files (see `locales/README.md` for conventions)
- **types/**: TypeScript type definitions

### Key Patterns
Expand Down Expand Up @@ -63,6 +64,17 @@ export const joinClient = {

**API Routes**: Use `unstable_cache` from Next.js for caching external API responses.

**Translations**: Uses `@onruntime/translations` package. See `apps/web/src/locales/README.md` for full conventions.
```typescript
// Server Components
import { getTranslation } from "@/lib/translations.server";
const { t } = await getTranslation("layout/footer");

// Client Components
import { useTranslation } from "@onruntime/translations/react";
const { t } = useTranslation("layout/footer");
```

## Environment Variables

Required for runtime (optional for build):
Expand Down
5 changes: 2 additions & 3 deletions apps/web/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ export const env = createEnv({
RESEND_API_KEY: z.string().optional(),
},
client: {
NEXT_PUBLIC_APP_URL: z.string().optional(),
NEXT_PUBLIC_APP_URL: z.string().optional().default("https://onruntime.com"),
},
runtimeEnv: {
NEXT_PUBLIC_APP_URL:
process.env.NEXT_PUBLIC_APP_URL || "https://onruntime.com",
NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,
NODE_ENV: process.env.NODE_ENV,
PORT: process.env.PORT,
JOIN_API_KEY: process.env.JOIN_API_KEY,
Expand Down
54 changes: 0 additions & 54 deletions apps/web/next-sitemap.config.js

This file was deleted.

8 changes: 8 additions & 0 deletions apps/web/next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ const nextConfig: NextConfig = {
});
return config;
},
async rewrites() {
return [
{
source: "/sitemap-:id.xml",
destination: "/sitemap.xml/:id",
},
];
},
async redirects() {
return [
{
Expand Down
6 changes: 4 additions & 2 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"scripts": {
"dev": "next dev --turbopack",
"build": "next build",
"postbuild": "next-sitemap",
"start": "next start",
"type-check": "tsc --noEmit"
},
Expand All @@ -15,8 +14,11 @@
"@mdx-js/loader": "^3.1.0",
"@mdx-js/react": "^3.1.0",
"@next/mdx": "^16.1.1",
"@onruntime/next-sitemap": "workspace:*",
"@onruntime/translations": "workspace:*",
"@radix-ui/react-accordion": "^1.2.3",
"@radix-ui/react-dialog": "^1.1.6",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-navigation-menu": "^1.2.3",
"@radix-ui/react-slot": "^1.1.1",
"@radix-ui/react-tabs": "^1.1.2",
Expand All @@ -35,13 +37,13 @@
"next-mdx-remote": "^5.0.0",
"next-mdx-remote-client": "^2.1.1",
"next-seo": "^6.6.0",
"next-sitemap": "^4.2.3",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-hook-form": "^7.54.2",
"react-wrap-balancer": "^1.1.1",
"reflect-metadata": "^0.2.2",
"resend": "^4.1.2",
"server-only": "^0.0.1",
"tailwind-merge": "^3.0.0",
"tailwindcss-animate": "^1.0.7",
"usehooks-ts": "^3.1.1",
Expand Down
9 changes: 0 additions & 9 deletions apps/web/src/app/(landing)/customer/page.ts

This file was deleted.

9 changes: 0 additions & 9 deletions apps/web/src/app/(landing)/page.ts

This file was deleted.

13 changes: 13 additions & 0 deletions apps/web/src/app/[locale]/(landing)/customer/page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { constructMetadata } from "@/lib/utils/metadata.server";
import { getTranslation } from "@/lib/translations.server";
import CustomerLanding from "@/screens/marketing/landing/customer";

export async function generateMetadata() {
const { t } = await getTranslation("app/landing/customer/page");
return constructMetadata({
title: t("metadata.title"),
description: t("metadata.description"),
});
}

export default CustomerLanding;
13 changes: 13 additions & 0 deletions apps/web/src/app/[locale]/(landing)/page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { constructMetadata } from "@/lib/utils/metadata.server";
import { getTranslation } from "@/lib/translations.server";
import VisitorLanding from "@/screens/marketing/landing/visitor";

export async function generateMetadata() {
const { t } = await getTranslation("app/landing/page");
return constructMetadata({
title: t("metadata.title"),
description: t("metadata.description"),
});
}

export default VisitorLanding;
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
import LegalPage from "@/components/marketing/legal/page"
import { getPageContent } from "@/lib/mdx"
import { constructMetadata } from "@/lib/utils/metadata"
import { constructMetadata } from "@/lib/utils/metadata.server"
import type { Metadata } from "next"

const contentPath = "legal/company"

export async function generateMetadata(): Promise<Metadata> {
const { frontmatter } = await getPageContent(contentPath)
type PageProps = {
params: Promise<{ locale: string }>
}

export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
const { locale } = await params
const { frontmatter } = await getPageContent(contentPath, locale)
return constructMetadata({
title: `${frontmatter.title}`,
description: frontmatter.description,
})
}

const CompanyPage = async () => {
const { frontmatter, content } = await getPageContent(contentPath)
const CompanyPage = async ({ params }: PageProps) => {
const { locale } = await params
const { frontmatter, content } = await getPageContent(contentPath, locale)

return <LegalPage title={frontmatter.title} description={frontmatter.description} content={content} lastUpdated={frontmatter.lastUpdated} />
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import LegalPage from "@/components/marketing/legal/page"
import { getPageContent } from "@/lib/mdx"
import { constructMetadata } from "@/lib/utils/metadata"
import { constructMetadata } from "@/lib/utils/metadata.server"
import type { Metadata } from "next"

const contentPath = "legal/privacy"

export async function generateMetadata(): Promise<Metadata> {
const { frontmatter } = await getPageContent(contentPath)
type PageProps = {
params: Promise<{ locale: string }>
}

export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
const { locale } = await params
const { frontmatter } = await getPageContent(contentPath, locale)
return constructMetadata({
title: `${frontmatter.title}`,
description: frontmatter.description,
})
}

const PrivacyPage = async () => {
const { frontmatter, content } = await getPageContent(contentPath)
const PrivacyPage = async ({ params }: PageProps) => {
const { locale } = await params
const { frontmatter, content } = await getPageContent(contentPath, locale)

return <LegalPage title={frontmatter.title} description={frontmatter.description} content={content} lastUpdated={frontmatter.lastUpdated} />
}

export default PrivacyPage
export default PrivacyPage
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import LegalPage from "@/components/marketing/legal/page"
import { getPageContent } from "@/lib/mdx"
import { constructMetadata } from "@/lib/utils/metadata"
import { constructMetadata } from "@/lib/utils/metadata.server"
import type { Metadata } from "next"

const contentPath = "legal/terms"

export async function generateMetadata(): Promise<Metadata> {
const { frontmatter } = await getPageContent(contentPath)
type PageProps = {
params: Promise<{ locale: string }>
}

export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
const { locale } = await params
const { frontmatter } = await getPageContent(contentPath, locale)
return constructMetadata({
title: `${frontmatter.title}`,
description: frontmatter.description,
})
}

const TermsPage = async () => {
const { frontmatter, content } = await getPageContent(contentPath)
const TermsPage = async ({ params }: PageProps) => {
const { locale } = await params
const { frontmatter, content } = await getPageContent(contentPath, locale)

return <LegalPage title={frontmatter.title} description={frontmatter.description} content={content} lastUpdated={frontmatter.lastUpdated} />
}

export default TermsPage
export default TermsPage
Loading