Skip to content

Commit

Permalink
Merge branch 'main' of github.com:opral/monorepo
Browse files Browse the repository at this point in the history
  • Loading branch information
NilsJacobsen committed Aug 8, 2024
2 parents 6ded738 + fe56d6e commit 260b66e
Show file tree
Hide file tree
Showing 27 changed files with 14,867 additions and 17,813 deletions.
19 changes: 19 additions & 0 deletions .changeset/dry-jobs-retire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
"@inlang/paraglide-next": minor
---

[Typed routes](https://nextjs.org/docs/app/api-reference/next-config-js/typedRoutes) are now supported. This adds typesafety to functions that expect an internal link.

- `<Link>`s now have typesafe `href` attributes
- `useRouter` now has has typesafe path arguments

```ts
import { paraglide } from "@inlang/paraglide-next/plugin"

export default paraglide({
experimental: {
typedRoutes: true, // enable this
},
paraglide: { ... },
})
```
6 changes: 6 additions & 0 deletions .changeset/long-carrots-cover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@inlang/paraglide-unplugin": patch
"@inlang/paraglide-js": patch
---

fix internal issues
16 changes: 16 additions & 0 deletions cla-signatures.json
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,22 @@
"created_at": "2024-07-24T10:02:38Z",
"repoId": 394757291,
"pullRequestNo": 3025
},
{
"name": "jonathanschoonbroodt",
"id": 33702771,
"comment_id": 2263078256,
"created_at": "2024-08-01T13:39:18Z",
"repoId": 394757291,
"pullRequestNo": 3038
},
{
"name": "azezsan",
"id": 79533966,
"comment_id": 2272796191,
"created_at": "2024-08-07T07:22:31Z",
"repoId": 394757291,
"pullRequestNo": 3047
}
]
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
{
"site_title": "Paraglide + Astro Beispiel",
"site_description": "Ein Beispiel für die Verwendung von Paraglide und Astro",
"follow_us_on": "Folge uns auf {site}",
"view_on": "Siehe auf {site}",
"all_rights_reserved": "Alle Rechte vorbehalten",
"count": "Der Zählerstand ist: {count}",
"english": "Englisch",
"german": "Deutsch"
}
"site_title": "Paraglide + Astro Beispiel",
"site_description": "Ein Beispiel für die Verwendung von Paraglide und Astro",
"follow_us_on": "Folge uns auf {site}",
"view_on": "Siehe auf {site}",
"all_rights_reserved": "Alle Rechte vorbehalten",
"count": "Der Zählerstand ist: {count}",
"english": "Englisch",
"german": "Deutsch",
"page_not_found": "Seite nicht gefunden"
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
{
"site_title": "Paraglide + Astro Example",
"site_description": "A simple example of using Paraglide with Astro",
"follow_us_on": "Follow us on {site}",
"view_on": "View on {site}",
"all_rights_reserved": "All rights reserved",
"count": "The current count is {count}",
"english": "English",
"german": "German"
}
"site_title": "Paraglide + Astro Example",
"site_description": "A simple example of using Paraglide with Astro",
"follow_us_on": "Follow us on {site}",
"view_on": "View on {site}",
"all_rights_reserved": "All rights reserved",
"count": "The current count is {count}",
"english": "English",
"german": "German",
"page_not_found": "Page not found"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
import HTML from '../layouts/HTML.astro';
import * as m from "$paraglide/messages";
---

<HTML>
<h1>{m.page_not_found()}</h1>
</HTML>
5 changes: 4 additions & 1 deletion inlang/source-code/paraglide/paraglide-astro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,8 @@
"seo",
"accessibility",
"withastro"
]
],
"devDependencies": {
"typescript": "^5.5.4"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ describe.each(["regular", "message-modules"] as const)("paraglide", async functi
const output = await compile({
messages: [],
settings: { languageTags: ["en", "de"], sourceLanguageTag: "en", modules: [] },
projectId: undefined,
})
expect(output["messages/en.js"]).includes("export {}")
expect(output["messages/de.js"]).includes("export {}")
Expand Down Expand Up @@ -531,5 +532,6 @@ describe.each(["regular", "message-modules"] as const)("paraglide", async functi
messages: mockMessages,
settings: mockSettings,
outputStructure: outputStyle,
projectId: undefined,
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const ignoreDirectory = `# ignore everything because the directory is auto-gener
export type CompileOptions = {
messages: Readonly<Message[]>
settings: ProjectSettings
projectId?: string | undefined
projectId: string | undefined
/**
* The file-structure of the compiled output.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,50 +34,49 @@ const strategy = DetectionStrategy<AvailableLanguageTag>()

> Manual Language switches only work if JS is enabled when using this strategy.

### Custom Strategy

The beatuy of the `RoutingStrategy` interface is that you can easily create your own routing strategy. All you need to do is implement the following functions:

```ts
const MyStrategy: RoutingStrategy<AvailableLanguageTag> = {
/**
* This function is called inside the middleware to determine the language for the current request.
*
* It's also OK to say you don't know & return undefined. In that case the Language Cookie will be used,
* This function is called inside the middleware to determine the language for the current request.
*
* It's also OK to say you don't know & return undefined. In that case the Language Cookie will be used,
* or Language negotiation if no cookie is present.
*/
resolveLocale(request: NextRequest) : AvailableLanguageTag | undefined

/**
* Returns the canonical pathname based on the localised pathname and it's language.
*
* The canonical pathname is the pathname you would need to get to the page you want
*
* The canonical pathname is the pathname you would need to get to the page you want
* in the `app/` directory if there weren't any i18n routing.
*
*
* @example /de/ueber-uns + de -> /about
*
*
*/
getCanonicalPath(
localisedPath: `/${string}`,
localisedPath: `/${string}`,
locale: AvailableLanguageTag
): `/${string}`


/**
* Returns the localized URL that can be used to navigate to the given path in the given language.
* It's a URL & not just a pathname so you can add query params and use other domains.
*
* It's a URL & not just a pathname so you can add query params and use other domains.
*
* For some strategies you might need to return different URLs based on if it's a language switch or not.
*
*
* @example /about + de -> /de/ueber-uns
*/
getLocalisedUrl(
canonicalPath: `/${string}`,
targetLocale: AvailableLanguageTag,
canonicalPath: `/${string}`,
targetLocale: AvailableLanguageTag,
isLanugageSwitch: boolean
) : import("url").UrlObject
}
```

To get some inspiration you might want to read the source-code of the built-in strategies.
To get some inspiration you might want to read the source-code of the built-in strategies.
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ export default paraglide({

basePath: "/base",
output: "standalone",
experimental: {
typedRoutes: true,
},
})
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Link } from "@/lib/i18n"
import * as m from "@/paraglide/messages.js"

export default function Home() {
return (
<>
<Link href="/about">About</Link>
<h1>{m.paraglide_and_next_app_router()}</h1>
<p>{m.this_app_was_localised_with_paraglide()}</p>
<p>{m.switch_languages_in_top_right()}</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"use client"
import { availableLanguageTags, AvailableLanguageTag, languageTag } from "@/paraglide/runtime"
import { usePathname, useRouter } from "@/lib/i18n"
import { Route } from "next"

export function SelectLanguage() {
const pathname = usePathname()
const pathname = usePathname() as Route
const router = useRouter()

const labels: Record<AvailableLanguageTag, string> = {
Expand Down
1 change: 1 addition & 0 deletions inlang/source-code/paraglide/paraglide-next/plugins.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ if (typeof version !== "string") {
export const plugins = [
typescript({
tsconfig: "./tsconfig.json",
exclude: ["**/node_modules/**/*"],
}),
cjs(),
resolve({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,38 @@ import {
} from "$paraglide/runtime.js"
import { addBasePath, basePath } from "../utils/basePath"
import NextLink from "next/link"
import React from "react"
import { RoutingStrategy } from "../routing-strategy/interface"
import React, { ComponentProps } from "react"
import { createLocaliseHref } from "../localiseHref"
import { serializeCookie } from "../utils/cookie"
import { LANG_COOKIE } from "../constants"
import { rsc } from "rsc-env"
import { DEV } from "../env"
import type { RoutingStrategy } from "../routing-strategy/interface"

type LocalisedLink<T extends string> = (
props: Omit<Parameters<typeof import("next/link").default>[0], "locale"> & { locale?: T }
export type LocalizedLink<T extends string> = (
props: LocalizedLinkProps<T>
) => ReturnType<typeof import("next/link").default>

type LocalizedLinkProps<T extends string> = Omit<
ComponentProps<typeof import("next/link").default>,
"locale"
> & { locale?: T }

/**
* Creates a link component that localises the href based on the current language.
* @param languageTag A function that returns the current language tag.
*/
export function createLink<T extends string>(strategy: RoutingStrategy<T>): LocalisedLink<T> {
export function createLink<T extends string>(strategy: RoutingStrategy<T>) {
const localiseHref = createLocaliseHref(strategy)

return React.forwardRef<
HTMLAnchorElement,
Omit<Parameters<typeof NextLink>[0], "locale"> & { locale?: T }
>((props, ref): ReturnType<typeof NextLink> => {
const Link: LocalizedLink<T> = React.forwardRef((props, ref) => {
const currentLanguageTag = languageTag() as T

if (DEV && props.locale && !isAvailableLanguageTag(props.locale)) {
const disjunctionFormatter = new Intl.ListFormat("en", { style: "long", type: "disjunction" })
const disjunctionFormatter = new Intl.ListFormat("en", {
style: "long",
type: "disjunction",
})
const availableLanguageTagsString = disjunctionFormatter.format(
availableLanguageTags.map((tag) => `"${tag}"`)
)
Expand Down Expand Up @@ -69,4 +74,6 @@ export function createLink<T extends string>(strategy: RoutingStrategy<T>): Loca
/>
)
})

return Link
}
Loading

0 comments on commit 260b66e

Please sign in to comment.