Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions app/entry.server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ export default async function handleRequest(
const callbackName = isbot(request.headers.get("user-agent")) ? "onAllReady" : "onShellReady"
const instance = createInstance()
const lng = appContext.lang
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
const ns = i18nextOpts.getRouteNamespaces(context as any)
const ns = i18nextOpts.getRouteNamespaces(context)

await instance
.use(initReactI18next) // Tell our instance to use react-i18next
Expand Down
4 changes: 2 additions & 2 deletions app/env.server.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { z } from "zod"
import { z } from "zod/v4"

const envSchema = z.object({
NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
Expand All @@ -13,7 +13,7 @@ let env: ServerEnv
* @returns Initialized env vars
*/
function initEnv() {
// biome-ignore lint/nursery/noProcessEnv: This should be the only place to use process.env directly
// biome-ignore lint/style/noProcessEnv: This should be the only place to use process.env directly
const envData = envSchema.safeParse(process.env)

if (!envData.success) {
Expand Down
1 change: 1 addition & 0 deletions app/library/link/Link.browser.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { userEvent } from "@vitest/browser/context"
import { useLocation } from "react-router"
import type { StubRouteEntry } from "tests/setup.browser"
import { Link, type LinkProps } from "./link"

const getEntries: (linkProps?: LinkProps) => StubRouteEntry[] = (linkProps) => [
{
path: "/first",
Expand Down
8 changes: 6 additions & 2 deletions app/library/link/useEnhancedTo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,15 @@ export const useEnhancedTo = ({
language,
to,
keepSearchParams,
}: { language?: Language; to: To; keepSearchParams?: boolean }) => {
}: {
language?: Language
to: To
keepSearchParams?: boolean
}) => {
const [params] = useSearchParams()
const { lng, ...searchParams } = Object.fromEntries(params.entries())
// allow language override for language switcher or manually setting the language in specific cases
const lang = language ?? params.get("lng")
const lang = language ?? lng
const newSearchParams = new URLSearchParams(searchParams)
const searchString = newSearchParams.toString()
const hasSearchParams = searchString.length > 0
Expand Down
2 changes: 1 addition & 1 deletion app/localization/resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const languages = ["en", "bs"] as const
export const supportedLanguages = [...languages]
export type Language = (typeof languages)[number]

type Resource = {
export type Resource = {
common: typeof english
}

Expand Down
2 changes: 1 addition & 1 deletion app/root.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useTranslation } from "react-i18next"
import { Links, Meta, Outlet, Scripts, ScrollRestoration, isRouteErrorResponse, useRouteError } from "react-router"
import type { LinksFunction } from "react-router"
import { isRouteErrorResponse, Links, Meta, Outlet, Scripts, ScrollRestoration, useRouteError } from "react-router"
import { useChangeLanguage } from "remix-i18next/react"
import type { Route } from "./+types/root"
import { LanguageSwitcher } from "./library/language-switcher"
Expand Down
16 changes: 4 additions & 12 deletions app/routes/resource.locales.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
import { cacheHeader } from "pretty-cache-header"
import { z } from "zod"
import { resources } from "~/localization/resource"
import { z } from "zod/v4"
import { type Language, type Namespace, resources } from "~/localization/resource"
import type { Route } from "./+types/resource.locales"

export async function loader({ request, context }: Route.LoaderArgs) {
const { isProductionDeployment } = context
const url = new URL(request.url)

const lng = z
.string()
.refine((lng): lng is keyof typeof resources => Object.keys(resources).includes(lng))
.parse(url.searchParams.get("lng"))
const lng = z.enum(Object.keys(resources) as Language[]).parse(url.searchParams.get("lng"))

const namespaces = resources[lng]

const ns = z
.string()
.refine((ns): ns is keyof typeof namespaces => {
return Object.keys(resources[lng]).includes(ns)
})
.parse(url.searchParams.get("ns"))
const ns = z.enum(Object.keys(resources[lng]) as Namespace[]).parse(url.searchParams.get("ns"))

const headers = new Headers()

Expand Down
1 change: 0 additions & 1 deletion app/routes/sitemap.$lang[.]xml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import type { Route } from "./+types/sitemap.$lang[.]xml"
export const loader = async ({ request, params }: Route.LoaderArgs) => {
const domain = createDomain(request)

// @ts-expect-error - This import exists but is not picked up by the typescript compiler because it's a remix internal
const { routes } = await import("virtual:react-router/server-build")

const sitemap = await generateRemixSitemap({
Expand Down
2 changes: 1 addition & 1 deletion app/tailwind.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@import "tailwindcss";

/** biome-ignore lint/nursery/noUnknownAtRule: This is a rule for the Tailwind CSS file */
@theme {
/* Your theme styles go here */
--animate-float: float 3s ease-in-out infinite;
Expand Down
20 changes: 14 additions & 6 deletions biome.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
"files": {
"ignore": ["app/library/icon/**/*"]
"includes": ["**", "!**/app/library/icon/**/*"]
},
"vcs": {
"enabled": true,
Expand All @@ -13,9 +13,7 @@
"enabled": true,
"lineWidth": 120
},
"organizeImports": {
"enabled": true
},
"assist": { "actions": { "source": { "organizeImports": "on" } } },
"linter": {
"enabled": true,
"rules": {
Expand All @@ -25,7 +23,18 @@
"noConsole": "error"
},
"style": {
"recommended": true
"recommended": true,
"noParameterAssign": "error",
"useAsConstAssertion": "error",
"useDefaultParameterLast": "error",
"useEnumInitializers": "error",
"useSelfClosingElements": "error",
"useSingleVarDeclarator": "error",
"noUnusedTemplateLiteral": "error",
"useNumberNamespace": "error",
"noInferrableTypes": "error",
"noUselessElse": "error",
"noProcessEnv": "error"
},
"complexity": {
"recommended": true
Expand All @@ -48,7 +57,6 @@
},
"nursery": {
"recommended": true,
"noProcessEnv": "error",
"useSortedClasses": {
"level": "error",
"fix": "safe",
Expand Down
97 changes: 51 additions & 46 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,68 +27,73 @@
"postinstall": "pnpm run typegen"
},
"dependencies": {
"@epic-web/client-hints": "1.3.5",
"@forge42/seo-tools": "1.3.0",
"@react-router/node": "7.2.0",
"@epic-web/client-hints": "1.3.7",
"@forge42/seo-tools": "1.4.5",
"@react-router/node": "7.6.3",
"clsx": "2.1.1",
"hono": "4.6.20",
"i18next": "24.2.2",
"i18next-browser-languagedetector": "8.0.2",
"hono": "4.8.4",
"i18next": "25.3.1",
"i18next-browser-languagedetector": "8.2.0",
"i18next-http-backend": "3.0.2",
"isbot": "5.1.22",
"isbot": "5.1.28",
"pretty-cache-header": "1.0.0",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-i18next": "15.4.0",
"react-router": "7.2.0",
"react-router-hono-server": "2.10.0",
"react": "19.1.0",
"react-dom": "19.1.0",
"react-i18next": "15.6.0",
"react-router": "7.6.3",
"react-router-hono-server": "2.13.0",
"remix-hono": "0.0.18",
"remix-i18next": "7.0.2",
"tailwind-merge": "3.0.1",
"zod": "3.24.1"
"remix-i18next": "7.2.1",
"tailwind-merge": "3.3.1",
"zod": "3.25.74"
},
"devDependencies": {
"@babel/preset-typescript": "7.26.0",
"@biomejs/biome": "1.9.4",
"@dotenvx/dotenvx": "1.34.0",
"@react-router/dev": "7.2.0",
"@react-router/fs-routes": "7.2.0",
"@tailwindcss/vite": "4.0.9",
"@testing-library/react": "16.2.0",
"@types/node": "22.13.1",
"@babel/preset-typescript": "7.27.1",
"@biomejs/biome": "2.0.6",
"@dotenvx/dotenvx": "1.45.2",
"@react-router/dev": "7.6.3",
"@react-router/fs-routes": "7.6.3",
"@tailwindcss/vite": "4.1.11",
"@testing-library/react": "16.3.0",
"@types/node": "24.0.10",
"@types/prompt": "1.1.9",
"@types/react": "19.0.8",
"@types/react-dom": "19.0.3",
"@vitest/browser": "3.0.5",
"@vitest/coverage-v8": "3.0.5",
"@vitest/ui": "3.0.5",
"babel-plugin-react-compiler": "19.0.0-beta-df7b47d-20241124",
"@types/react": "19.1.8",
"@types/react-dom": "19.1.6",
"@vitest/browser": "3.2.4",
"@vitest/coverage-v8": "3.2.4",
"@vitest/ui": "3.2.4",
"babel-plugin-react-compiler": "19.1.0-rc.2",
"chalk": "5.4.1",
"happy-dom": "16.8.1",
"knip": "5.43.6",
"lefthook": "1.10.10",
"playwright": "1.50.1",
"happy-dom": "18.0.1",
"knip": "5.61.3",
"lefthook": "1.11.16",
"playwright": "1.53.2",
"prompt": "1.3.0",
"react-router-devtools": "5.0.4",
"tailwindcss": "4.0.9",
"tsx": "4.19.2",
"typescript": "5.7.3",
"vite": "6.2.0",
"vite-plugin-babel": "1.3.0",
"react-router-devtools": "5.0.6",
"tailwindcss": "4.1.11",
"tsx": "4.20.3",
"typescript": "5.8.3",
"vite": "7.0.2",
"vite-plugin-babel": "1.3.2",
"vite-plugin-icons-spritesheet": "3.0.1",
"vite-tsconfig-paths": "5.1.4",
"vitest": "3.0.5",
"vitest-browser-react": "0.0.4"
"vitest": "3.2.4",
"vitest-browser-react": "1.0.0"
},
"packageManager": "pnpm@10.2.0",
"packageManager": "pnpm@10.12.4",
"optionalDependencies": {
"@rollup/rollup-linux-x64-gnu": "^4.34.3"
"@rollup/rollup-linux-x64-gnu": "^4.44.2"
},
"engines": {
"node": ">=22.11.0",
"pnpm": ">=10.2.0"
"node": ">=24.3.0",
"pnpm": ">=10.12.4"
},
"pnpm": {
"onlyBuiltDependencies": ["@biomejs/biome", "esbuild", "lefthook", "msw"]
"onlyBuiltDependencies": [
"@biomejs/biome",
"esbuild",
"lefthook",
"msw"
]
}
}
Loading