diff --git a/.prettierignore b/.prettierignore
index e794a80b7..4d2302555 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -10,3 +10,7 @@ CONTRIBUTING.md
docs
.next
.cache
+
+# Generated files
+CHANGELOG.md
+**/api-report/*
\ No newline at end of file
diff --git a/packages/elements-react/src/locales/de.json b/packages/elements-react/src/locales/de.json
index fa6395128..b86ae6108 100644
--- a/packages/elements-react/src/locales/de.json
+++ b/packages/elements-react/src/locales/de.json
@@ -201,5 +201,23 @@
"identities.messages.1050020": "",
"identities.messages.4000037": "",
"identities.messages.4010009": "",
- "identities.messages.4010010": ""
+ "identities.messages.4010010": "",
+ "input.placeholder": "{placeholder} eingeben",
+ "card.header.parts.code": "einem Code per E-Mail",
+ "card.header.parts.identifier-first": "Ihr {identifierLabel}",
+ "card.header.parts.oidc": "ein sozialer Anbieter",
+ "card.header.parts.passkey": "ein Passkey",
+ "card.header.parts.password.login": "Ihrer {identifierLabel} und Ihrem Passwort",
+ "card.header.parts.password.registration": "Ihrer {identifierLabel} und einem Passwort",
+ "card.header.parts.webauthn": "ein Sicherheitsschlüssel",
+ "recovery.subtitle": "Geben Sie die mit Ihrem Konto verknüpfte E-Mail-Adresse ein, um einen einmaligen Zugangscode zu erhalten",
+ "settings.subtitle": "Aktualisieren Sie Ihre Kontoeinstellungen",
+ "verification.subtitle": "Geben Sie die mit Ihrem Konto verknüpfte E-Mail-Adresse ein, um es zu bestätigen",
+ "card.header.description.login": "Melden Sie sich mit {identifierLabel} an",
+ "card.header.description.registration": "Registrieren Sie sich mit {identifierLabel}",
+ "login.subtitle": "Melden Sie sich mit {parts} an",
+ "login.subtitle-refresh": "Bestätigen Sie ihre Identität mit {parts}",
+ "misc.or": "oder",
+ "registration.subtitle": "Registrieren Sie sich mit {parts}",
+ "forms.label.forgot-password": "Passwort vergessen?"
}
diff --git a/packages/elements-react/src/locales/en.json b/packages/elements-react/src/locales/en.json
index 59dcf4595..63d2b945f 100644
--- a/packages/elements-react/src/locales/en.json
+++ b/packages/elements-react/src/locales/en.json
@@ -158,18 +158,22 @@
"login.registration-label": "Don't have an account?",
"login.subtitle-oauth2": "To authenticate {clientName}",
"login.title": "Sign in",
+ "login.subtitle": "Sign in with {parts}",
"login.title-aal2": "Two-Factor Authentication",
- "login.title-refresh": "Confirm it's you",
+ "login.title-refresh": "Reauthenticate",
+ "login.subtitle-refresh": "Confirm your identity with {parts}",
"logout.accept-button": "Yes",
"logout.reject-button": "No",
"logout.title": "Do you wish to log out?",
"recovery.login-button": "Sign in",
"recovery.login-label": "Remember your credentials?",
"recovery.title": "Recover your account",
+ "recovery.subtitle": "Enter the email address associated with your account to receive a one-time access code",
"registration.login-button": "Sign in",
"registration.login-label": "Already have an account?",
"registration.subtitle-oauth2": "To authenticate {clientName}",
"registration.title": "Register an account",
+ "registration.subtitle": "Sign up with {parts}",
"settings.navigation-back-button": "Back",
"settings.navigation-backup-codes": "2FA Backup Codes",
"settings.navigation-logout": "Logout",
@@ -180,7 +184,8 @@
"settings.navigation-webauthn": "Hardware Tokens",
"settings.navigation-passkey": "Passkeys",
"settings.subtitle-instructions": "Here you can manage settings related to your account. Keep in mind that certain actions require you to re-authenticate.",
- "settings.title": "Account Settings",
+ "settings.title": "Update your account",
+ "settings.subtitle": "Update your account settings",
"settings.title-lookup-secret": "Manage 2FA Backup Recovery Codes",
"settings.title-navigation": "Account Settings",
"settings.title-oidc": "Social Sign In",
@@ -192,6 +197,7 @@
"verification.registration-button": "Sign up",
"verification.registration-label": "Don't have an account?",
"verification.title": "Verify your account",
+ "verification.subtitle": "Enter the email address associated with your account to verify it",
"verification.back-button": "Back",
"two-step.password.title": "Password",
"two-step.password.description": "Enter your password associated with your account",
@@ -201,5 +207,17 @@
"two-step.webauthn.description": "Use your security key to authenticate",
"two-step.passkey.title": "Passkey (recommended)",
"two-step.passkey.description": "Use your device's for fingerprint or face recognition",
- "identities.messages.1010020": ""
+ "identities.messages.1010020": "",
+ "input.placeholder": "Enter your {placeholder}",
+ "card.header.parts.oidc": "a social provider",
+ "card.header.parts.password.registration": "your {identifierLabel} and a password",
+ "card.header.parts.password.login": "your {identifierLabel} and password",
+ "card.header.parts.code": "a code sent to your email",
+ "card.header.parts.passkey": "a Passkey",
+ "card.header.parts.webauthn": "a security key",
+ "card.header.parts.identifier-first": "your {identifierLabel}",
+ "card.header.description.login": "Sign in with {identifierLabel}",
+ "card.header.description.registration": "Sign up with {identifierLabel}",
+ "misc.or": "or",
+ "forms.label.forgot-password": "Forgot Password?"
}
diff --git a/packages/elements-react/src/locales/es.json b/packages/elements-react/src/locales/es.json
index a8701cbc6..b9459aba8 100644
--- a/packages/elements-react/src/locales/es.json
+++ b/packages/elements-react/src/locales/es.json
@@ -201,5 +201,23 @@
"identities.messages.4010009": "",
"identities.messages.4010010": "",
"login.cancel-button": "",
- "login.cancel-label": ""
+ "login.cancel-label": "",
+ "input.placeholder": "",
+ "card.header.description.login": "",
+ "card.header.description.registration": "",
+ "card.header.parts.code": "",
+ "card.header.parts.identifier-first": "",
+ "card.header.parts.oidc": "",
+ "card.header.parts.passkey": "",
+ "card.header.parts.password.login": "",
+ "card.header.parts.password.registration": "",
+ "card.header.parts.webauthn": "",
+ "forms.label.forgot-password": "",
+ "login.subtitle": "",
+ "login.subtitle-refresh": "",
+ "misc.or": "",
+ "recovery.subtitle": "",
+ "registration.subtitle": "",
+ "settings.subtitle": "",
+ "verification.subtitle": ""
}
diff --git a/packages/elements-react/src/locales/fr.json b/packages/elements-react/src/locales/fr.json
index 783c02c5e..6944df10e 100644
--- a/packages/elements-react/src/locales/fr.json
+++ b/packages/elements-react/src/locales/fr.json
@@ -201,5 +201,23 @@
"identities.messages.1070014": "",
"identities.messages.4000037": "",
"identities.messages.4010009": "",
- "identities.messages.4010010": ""
+ "identities.messages.4010010": "",
+ "input.placeholder": "",
+ "card.header.description.login": "",
+ "card.header.description.registration": "",
+ "card.header.parts.code": "",
+ "card.header.parts.identifier-first": "",
+ "card.header.parts.oidc": "",
+ "card.header.parts.passkey": "",
+ "card.header.parts.password.login": "",
+ "card.header.parts.password.registration": "",
+ "card.header.parts.webauthn": "",
+ "forms.label.forgot-password": "",
+ "login.subtitle": "",
+ "login.subtitle-refresh": "",
+ "misc.or": "",
+ "recovery.subtitle": "",
+ "registration.subtitle": "",
+ "settings.subtitle": "",
+ "verification.subtitle": ""
}
diff --git a/packages/elements-react/src/locales/nl.json b/packages/elements-react/src/locales/nl.json
index 1ed1fcb8a..5e4d160b4 100644
--- a/packages/elements-react/src/locales/nl.json
+++ b/packages/elements-react/src/locales/nl.json
@@ -201,5 +201,23 @@
"identities.messages.1050020": "",
"identities.messages.4000037": "",
"identities.messages.4010009": "",
- "identities.messages.4010010": ""
+ "identities.messages.4010010": "",
+ "input.placeholder": "",
+ "card.header.description.login": "",
+ "card.header.description.registration": "",
+ "card.header.parts.code": "",
+ "card.header.parts.identifier-first": "",
+ "card.header.parts.oidc": "",
+ "card.header.parts.passkey": "",
+ "card.header.parts.password.login": "",
+ "card.header.parts.password.registration": "",
+ "card.header.parts.webauthn": "",
+ "forms.label.forgot-password": "",
+ "login.subtitle": "",
+ "login.subtitle-refresh": "",
+ "misc.or": "",
+ "recovery.subtitle": "",
+ "registration.subtitle": "",
+ "settings.subtitle": "",
+ "verification.subtitle": ""
}
diff --git a/packages/elements-react/src/locales/pl.json b/packages/elements-react/src/locales/pl.json
index eb2d94d1a..3fa0f6056 100644
--- a/packages/elements-react/src/locales/pl.json
+++ b/packages/elements-react/src/locales/pl.json
@@ -201,5 +201,23 @@
"identities.messages.4010009": "",
"identities.messages.4010010": "",
"login.cancel-button": "",
- "login.cancel-label": ""
+ "login.cancel-label": "",
+ "input.placeholder": "",
+ "card.header.description.login": "",
+ "card.header.description.registration": "",
+ "card.header.parts.code": "",
+ "card.header.parts.identifier-first": "",
+ "card.header.parts.oidc": "",
+ "card.header.parts.passkey": "",
+ "card.header.parts.password.login": "",
+ "card.header.parts.password.registration": "",
+ "card.header.parts.webauthn": "",
+ "forms.label.forgot-password": "",
+ "login.subtitle": "",
+ "login.subtitle-refresh": "",
+ "misc.or": "",
+ "recovery.subtitle": "",
+ "registration.subtitle": "",
+ "settings.subtitle": "",
+ "verification.subtitle": ""
}
diff --git a/packages/elements-react/src/locales/pt.json b/packages/elements-react/src/locales/pt.json
index 54b426d77..2646603eb 100644
--- a/packages/elements-react/src/locales/pt.json
+++ b/packages/elements-react/src/locales/pt.json
@@ -201,5 +201,23 @@
"identities.messages.4010010": "",
"login.cancel-button": "",
"login.cancel-label": "",
- "identities.messages.1070015": ""
+ "identities.messages.1070015": "",
+ "input.placeholder": "",
+ "card.header.description.login": "",
+ "card.header.description.registration": "",
+ "card.header.parts.code": "",
+ "card.header.parts.identifier-first": "",
+ "card.header.parts.oidc": "",
+ "card.header.parts.passkey": "",
+ "card.header.parts.password.login": "",
+ "card.header.parts.password.registration": "",
+ "card.header.parts.webauthn": "",
+ "forms.label.forgot-password": "",
+ "login.subtitle": "",
+ "login.subtitle-refresh": "",
+ "misc.or": "",
+ "recovery.subtitle": "",
+ "registration.subtitle": "",
+ "settings.subtitle": "",
+ "verification.subtitle": ""
}
diff --git a/packages/elements-react/src/locales/sv.json b/packages/elements-react/src/locales/sv.json
index 50bec3bbc..45f8d3b31 100644
--- a/packages/elements-react/src/locales/sv.json
+++ b/packages/elements-react/src/locales/sv.json
@@ -201,5 +201,23 @@
"two-step.webauthn.title": "Säkerhetsnyckel",
"identities.messages.4000037": "Detta konto finns inte eller har ingen inloggningsmetod konfigurerad.",
"identities.messages.4000038": "Captcha-verifiering misslyckades, försök igen.",
- "identities.messages.1010020": ""
+ "identities.messages.1010020": "",
+ "input.placeholder": "Ange ditt {placeholder}",
+ "card.header.description.login": "Logga in med {identifierLabel}",
+ "card.header.description.registration": "Registrera dig med {identifierLabel}",
+ "card.header.parts.code": "en kod skickad till din e-post",
+ "card.header.parts.identifier-first": "din {identifierLabel}",
+ "card.header.parts.oidc": "en social leverantör",
+ "card.header.parts.passkey": "en Passkey",
+ "card.header.parts.password.login": "din {identifierLabel} och lösenord",
+ "card.header.parts.password.registration": "din {identifierLabel} och ett lösenord",
+ "card.header.parts.webauthn": "en säkerhetsnyckel",
+ "forms.label.forgot-password": "Glömt Lösenord?",
+ "login.subtitle": "Logga in med {parts}",
+ "login.subtitle-refresh": "Bekräfta din identitet med {parts}",
+ "misc.or": "eller",
+ "recovery.subtitle": "Ange e-postadressen kopplad till ditt konto för att få en engångskod för åtkomst",
+ "registration.subtitle": "Registrera dig med {parts}",
+ "settings.subtitle": "Uppdatera dina kontoinställningar",
+ "verification.subtitle": "Ange e-postadressen kopplad till ditt konto för att verifiera det"
}
diff --git a/packages/elements-react/src/theme/default/components/card/header.tsx b/packages/elements-react/src/theme/default/components/card/header.tsx
index f360ea731..a48901302 100644
--- a/packages/elements-react/src/theme/default/components/card/header.tsx
+++ b/packages/elements-react/src/theme/default/components/card/header.tsx
@@ -1,5 +1,5 @@
import { useComponents, useOryFlow } from "@ory/elements-react"
-import { constructCardHeaderText } from "../../utils/constructCardHeader"
+import { useCardHeaderText } from "../../utils/constructCardHeader"
function InnerCardHeader({ title, text }: { title: string; text?: string }) {
const { CardLogo } = useComponents()
@@ -18,7 +18,7 @@ function InnerCardHeader({ title, text }: { title: string; text?: string }) {
export function DefaultCardHeader() {
const context = useOryFlow()
- const { title, description } = constructCardHeaderText(
+ const { title, description } = useCardHeaderText(
context.flow.ui.nodes,
context,
)
diff --git a/packages/elements-react/src/theme/default/components/form/index.tsx b/packages/elements-react/src/theme/default/components/form/index.tsx
index f2ec56377..1ad941fd7 100644
--- a/packages/elements-react/src/theme/default/components/form/index.tsx
+++ b/packages/elements-react/src/theme/default/components/form/index.tsx
@@ -1,7 +1,8 @@
import { PropsWithChildren } from "react"
import { cn } from "../../utils/cn"
-import { HeadlessFormProps } from "@ory/elements-react"
+import { formatMessage, HeadlessFormProps } from "@ory/elements-react"
import { HeadlessMessageProps } from "@ory/elements-react"
+import { useIntl } from "react-intl"
export function DefaultFormContainer({
children,
@@ -31,6 +32,7 @@ export function DefaultMessageContainer({ children }: PropsWithChildren) {
}
export function DefaultMessage({ message }: HeadlessMessageProps) {
+ const intl = useIntl()
return (
- {message.text}
+ {formatMessage(message, intl)}
)
}
diff --git a/packages/elements-react/src/theme/default/components/form/input.tsx b/packages/elements-react/src/theme/default/components/form/input.tsx
index cab18f567..ac456431f 100644
--- a/packages/elements-react/src/theme/default/components/form/input.tsx
+++ b/packages/elements-react/src/theme/default/components/form/input.tsx
@@ -1,6 +1,7 @@
-import { useFormContext } from "react-hook-form"
-import { HeadlessInputProps } from "@ory/elements-react"
import { getNodeLabel } from "@ory/client-fetch"
+import { formatMessage, HeadlessInputProps } from "@ory/elements-react"
+import { useFormContext } from "react-hook-form"
+import { useIntl } from "react-intl"
export const DefaultInput = ({
node,
@@ -10,6 +11,19 @@ export const DefaultInput = ({
const label = getNodeLabel(node)
const { register } = useFormContext()
const { value, autocomplete, name, maxlength, ...rest } = attributes
+ const intl = useIntl()
+
+ const formattedLabel = label
+ ? intl.formatMessage(
+ {
+ id: "input.placeholder",
+ defaultMessage: "Enter your {placeholder}",
+ },
+ {
+ placeholder: formatMessage(label, intl),
+ },
+ )
+ : ""
return (
diff --git a/packages/elements-react/src/theme/default/components/form/social.tsx b/packages/elements-react/src/theme/default/components/form/social.tsx
index 16e1a998e..9aa208bc2 100644
--- a/packages/elements-react/src/theme/default/components/form/social.tsx
+++ b/packages/elements-react/src/theme/default/components/form/social.tsx
@@ -1,10 +1,12 @@
import {
+ formatMessage,
HeadlessSocialButtonContainerProps,
HeadlessSocialButtonProps,
useOryFlow,
} from "@ory/elements-react"
import logos from "../../provider-logos"
import { cn } from "../../utils/cn"
+import { useIntl } from "react-intl"
function extractProvider(context: object | undefined): string | undefined {
if (
@@ -32,6 +34,7 @@ export function DefaultButtonSocial({
const {
flow: { ui },
} = useOryFlow()
+ const intl = useIntl()
const oidcNodeCount =
ui.nodes.filter((node) => node.group === "oidc").length ?? 0
@@ -69,7 +72,7 @@ export function DefaultButtonSocial({
{showLabel ? (
- {node.meta.label?.text}
+ {formatMessage(node.meta.label, intl)}
) : null}
diff --git a/packages/elements-react/src/theme/default/utils/__tests__/__snapshots__/constructCardHeader.spec.ts.snap b/packages/elements-react/src/theme/default/utils/__tests__/__snapshots__/constructCardHeader.spec.tsx.snap
similarity index 88%
rename from packages/elements-react/src/theme/default/utils/__tests__/__snapshots__/constructCardHeader.spec.ts.snap
rename to packages/elements-react/src/theme/default/utils/__tests__/__snapshots__/constructCardHeader.spec.tsx.snap
index 726a1b826..984f29995 100644
--- a/packages/elements-react/src/theme/default/utils/__tests__/__snapshots__/constructCardHeader.spec.ts.snap
+++ b/packages/elements-react/src/theme/default/utils/__tests__/__snapshots__/constructCardHeader.spec.tsx.snap
@@ -2,42 +2,42 @@
exports[`flowType=login refresh=false combination=code constructCardHeaderText 1`] = `
{
- "description": "Sign in with a code sent to your email.",
+ "description": "Sign in with a code sent to your email",
"title": "Sign in",
}
`;
exports[`flowType=login refresh=false combination=default_and_code constructCardHeaderText 1`] = `
{
- "description": "Sign in with a code sent to your email.",
+ "description": "Sign in with a code sent to your email",
"title": "Sign in",
}
`;
exports[`flowType=login refresh=false combination=default_and_oidc constructCardHeaderText 1`] = `
{
- "description": "Sign in with a social provider.",
+ "description": "Sign in with a social provider",
"title": "Sign in",
}
`;
exports[`flowType=login refresh=false combination=default_and_passkeys constructCardHeaderText 1`] = `
{
- "description": "Sign in with a Passkey.",
+ "description": "Sign in with a Passkey",
"title": "Sign in",
}
`;
exports[`flowType=login refresh=false combination=default_and_password constructCardHeaderText 1`] = `
{
- "description": "Sign in with your email and password.",
+ "description": "Sign in with your email and password",
"title": "Sign in",
}
`;
exports[`flowType=login refresh=false combination=default_and_webauthn constructCardHeaderText 1`] = `
{
- "description": "Sign in with a security key.",
+ "description": "Sign in with a security key",
"title": "Sign in",
}
`;
@@ -51,91 +51,91 @@ exports[`flowType=login refresh=false combination=defaultGroup constructCardHead
exports[`flowType=login refresh=false combination=idenfier_first_and_oidc constructCardHeaderText 1`] = `
{
- "description": "Sign in with a social provider or your undefined.",
+ "description": "Sign in with a social provider or your Email",
"title": "Sign in",
}
`;
exports[`flowType=login refresh=false combination=identifierFirst constructCardHeaderText 1`] = `
{
- "description": "Sign in with your undefined.",
+ "description": "Sign in with your Email",
"title": "Sign in",
}
`;
exports[`flowType=login refresh=false combination=identifierFirstPhone constructCardHeaderText 1`] = `
{
- "description": "Sign in with your undefined.",
+ "description": "Sign in with your Phone number",
"title": "Sign in",
}
`;
exports[`flowType=login refresh=false combination=oidc constructCardHeaderText 1`] = `
{
- "description": "Sign in with a social provider.",
+ "description": "Sign in with a social provider",
"title": "Sign in",
}
`;
exports[`flowType=login refresh=false combination=passkey constructCardHeaderText 1`] = `
{
- "description": "Sign in with a Passkey.",
+ "description": "Sign in with a Passkey",
"title": "Sign in",
}
`;
exports[`flowType=login refresh=false combination=password constructCardHeaderText 1`] = `
{
- "description": "Sign in with your email and password.",
+ "description": "Sign in with your email and password",
"title": "Sign in",
}
`;
exports[`flowType=login refresh=false combination=webauthn constructCardHeaderText 1`] = `
{
- "description": "Sign in with a security key.",
+ "description": "Sign in with a security key",
"title": "Sign in",
}
`;
exports[`flowType=login refresh=true combination=code constructCardHeaderText 1`] = `
{
- "description": "Confirm your identity with a code sent to your email.",
+ "description": "Confirm your identity with a code sent to your email",
"title": "Reauthenticate",
}
`;
exports[`flowType=login refresh=true combination=default_and_code constructCardHeaderText 1`] = `
{
- "description": "Confirm your identity with a code sent to your email.",
+ "description": "Confirm your identity with a code sent to your email",
"title": "Reauthenticate",
}
`;
exports[`flowType=login refresh=true combination=default_and_oidc constructCardHeaderText 1`] = `
{
- "description": "Confirm your identity with a social provider.",
+ "description": "Confirm your identity with a social provider",
"title": "Reauthenticate",
}
`;
exports[`flowType=login refresh=true combination=default_and_passkeys constructCardHeaderText 1`] = `
{
- "description": "Confirm your identity with a Passkey.",
+ "description": "Confirm your identity with a Passkey",
"title": "Reauthenticate",
}
`;
exports[`flowType=login refresh=true combination=default_and_password constructCardHeaderText 1`] = `
{
- "description": "Confirm your identity with your email and password.",
+ "description": "Confirm your identity with your email and password",
"title": "Reauthenticate",
}
`;
exports[`flowType=login refresh=true combination=default_and_webauthn constructCardHeaderText 1`] = `
{
- "description": "Confirm your identity with a security key.",
+ "description": "Confirm your identity with a security key",
"title": "Reauthenticate",
}
`;
@@ -149,49 +149,49 @@ exports[`flowType=login refresh=true combination=defaultGroup constructCardHeade
exports[`flowType=login refresh=true combination=idenfier_first_and_oidc constructCardHeaderText 1`] = `
{
- "description": "Confirm your identity with a social provider or your undefined.",
+ "description": "Confirm your identity with a social provider or your Email",
"title": "Reauthenticate",
}
`;
exports[`flowType=login refresh=true combination=identifierFirst constructCardHeaderText 1`] = `
{
- "description": "Confirm your identity with your undefined.",
+ "description": "Confirm your identity with your Email",
"title": "Reauthenticate",
}
`;
exports[`flowType=login refresh=true combination=identifierFirstPhone constructCardHeaderText 1`] = `
{
- "description": "Confirm your identity with your undefined.",
+ "description": "Confirm your identity with your Phone number",
"title": "Reauthenticate",
}
`;
exports[`flowType=login refresh=true combination=oidc constructCardHeaderText 1`] = `
{
- "description": "Confirm your identity with a social provider.",
+ "description": "Confirm your identity with a social provider",
"title": "Reauthenticate",
}
`;
exports[`flowType=login refresh=true combination=passkey constructCardHeaderText 1`] = `
{
- "description": "Confirm your identity with a Passkey.",
+ "description": "Confirm your identity with a Passkey",
"title": "Reauthenticate",
}
`;
exports[`flowType=login refresh=true combination=password constructCardHeaderText 1`] = `
{
- "description": "Confirm your identity with your email and password.",
+ "description": "Confirm your identity with your email and password",
"title": "Reauthenticate",
}
`;
exports[`flowType=login refresh=true combination=webauthn constructCardHeaderText 1`] = `
{
- "description": "Confirm your identity with a security key.",
+ "description": "Confirm your identity with a security key",
"title": "Reauthenticate",
}
`;
@@ -394,197 +394,197 @@ exports[`flowType=recovery refresh=true combination=webauthn constructCardHeader
exports[`flowType=registration refresh=false combination=code constructCardHeaderText 1`] = `
{
- "description": "Sign up with a code sent to your email.",
- "title": "Sign up",
+ "description": "Sign up with a code sent to your email",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=false combination=default_and_code constructCardHeaderText 1`] = `
{
- "description": "Sign up with a code sent to your email.",
- "title": "Sign up",
+ "description": "Sign up with a code sent to your email",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=false combination=default_and_oidc constructCardHeaderText 1`] = `
{
- "description": "Sign up with a social provider.",
- "title": "Sign up",
+ "description": "Sign up with a social provider",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=false combination=default_and_passkeys constructCardHeaderText 1`] = `
{
- "description": "Sign up with a Passkey.",
- "title": "Sign up",
+ "description": "Sign up with a Passkey",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=false combination=default_and_password constructCardHeaderText 1`] = `
{
- "description": "Sign up with your email and a password.",
- "title": "Sign up",
+ "description": "Sign up with your email and a password",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=false combination=default_and_webauthn constructCardHeaderText 1`] = `
{
- "description": "Sign up with a security key.",
- "title": "Sign up",
+ "description": "Sign up with a security key",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=false combination=defaultGroup constructCardHeaderText 1`] = `
{
"description": "",
- "title": "Sign up",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=false combination=idenfier_first_and_oidc constructCardHeaderText 1`] = `
{
- "description": "Sign up with a social provider or your undefined.",
- "title": "Sign up",
+ "description": "Sign up with a social provider or your Email",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=false combination=identifierFirst constructCardHeaderText 1`] = `
{
- "description": "Sign up with your undefined.",
- "title": "Sign up",
+ "description": "Sign up with your Email",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=false combination=identifierFirstPhone constructCardHeaderText 1`] = `
{
- "description": "Sign up with your undefined.",
- "title": "Sign up",
+ "description": "Sign up with your Phone number",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=false combination=oidc constructCardHeaderText 1`] = `
{
- "description": "Sign up with a social provider.",
- "title": "Sign up",
+ "description": "Sign up with a social provider",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=false combination=passkey constructCardHeaderText 1`] = `
{
- "description": "Sign up with a Passkey.",
- "title": "Sign up",
+ "description": "Sign up with a Passkey",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=false combination=password constructCardHeaderText 1`] = `
{
- "description": "Sign up with your email and a password.",
- "title": "Sign up",
+ "description": "Sign up with your email and a password",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=false combination=webauthn constructCardHeaderText 1`] = `
{
- "description": "Sign up with a security key.",
- "title": "Sign up",
+ "description": "Sign up with a security key",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=true combination=code constructCardHeaderText 1`] = `
{
- "description": "Sign up with a code sent to your email.",
- "title": "Sign up",
+ "description": "Sign up with a code sent to your email",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=true combination=default_and_code constructCardHeaderText 1`] = `
{
- "description": "Sign up with a code sent to your email.",
- "title": "Sign up",
+ "description": "Sign up with a code sent to your email",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=true combination=default_and_oidc constructCardHeaderText 1`] = `
{
- "description": "Sign up with a social provider.",
- "title": "Sign up",
+ "description": "Sign up with a social provider",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=true combination=default_and_passkeys constructCardHeaderText 1`] = `
{
- "description": "Sign up with a Passkey.",
- "title": "Sign up",
+ "description": "Sign up with a Passkey",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=true combination=default_and_password constructCardHeaderText 1`] = `
{
- "description": "Sign up with your email and a password.",
- "title": "Sign up",
+ "description": "Sign up with your email and a password",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=true combination=default_and_webauthn constructCardHeaderText 1`] = `
{
- "description": "Sign up with a security key.",
- "title": "Sign up",
+ "description": "Sign up with a security key",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=true combination=defaultGroup constructCardHeaderText 1`] = `
{
"description": "",
- "title": "Sign up",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=true combination=idenfier_first_and_oidc constructCardHeaderText 1`] = `
{
- "description": "Sign up with a social provider or your undefined.",
- "title": "Sign up",
+ "description": "Sign up with a social provider or your Email",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=true combination=identifierFirst constructCardHeaderText 1`] = `
{
- "description": "Sign up with your undefined.",
- "title": "Sign up",
+ "description": "Sign up with your Email",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=true combination=identifierFirstPhone constructCardHeaderText 1`] = `
{
- "description": "Sign up with your undefined.",
- "title": "Sign up",
+ "description": "Sign up with your Phone number",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=true combination=oidc constructCardHeaderText 1`] = `
{
- "description": "Sign up with a social provider.",
- "title": "Sign up",
+ "description": "Sign up with a social provider",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=true combination=passkey constructCardHeaderText 1`] = `
{
- "description": "Sign up with a Passkey.",
- "title": "Sign up",
+ "description": "Sign up with a Passkey",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=true combination=password constructCardHeaderText 1`] = `
{
- "description": "Sign up with your email and a password.",
- "title": "Sign up",
+ "description": "Sign up with your email and a password",
+ "title": "Register an account",
}
`;
exports[`flowType=registration refresh=true combination=webauthn constructCardHeaderText 1`] = `
{
- "description": "Sign up with a security key.",
- "title": "Sign up",
+ "description": "Sign up with a security key",
+ "title": "Register an account",
}
`;
diff --git a/packages/elements-react/src/theme/default/utils/__tests__/constructCardHeader.spec.ts b/packages/elements-react/src/theme/default/utils/__tests__/constructCardHeader.spec.tsx
similarity index 84%
rename from packages/elements-react/src/theme/default/utils/__tests__/constructCardHeader.spec.ts
rename to packages/elements-react/src/theme/default/utils/__tests__/constructCardHeader.spec.tsx
index 04fdb817b..1e8127d00 100644
--- a/packages/elements-react/src/theme/default/utils/__tests__/constructCardHeader.spec.ts
+++ b/packages/elements-react/src/theme/default/utils/__tests__/constructCardHeader.spec.tsx
@@ -2,7 +2,10 @@
// SPDX-License-Identifier: Apache-2.0
import { FlowType, UiNode, UiTextTypeEnum } from "@ory/client-fetch"
-import { constructCardHeaderText } from "../constructCardHeader"
+import { useCardHeaderText } from "../constructCardHeader"
+import { renderHook } from "@testing-library/react"
+import { PropsWithChildren } from "react"
+import { IntlProvider } from "../../../../context"
const password: UiNode = {
group: "password",
@@ -108,14 +111,15 @@ const identifierFirst: UiNode = {
type: "text",
value: "",
disabled: false,
+ },
+ messages: [],
+ meta: {
label: {
text: "Email",
type: UiTextTypeEnum.Info,
id: 9999,
},
},
- messages: [],
- meta: {},
}
const identifierFirstPhone: UiNode = {
@@ -127,14 +131,15 @@ const identifierFirstPhone: UiNode = {
type: "text",
value: "",
disabled: false,
+ },
+ messages: [],
+ meta: {
label: {
text: "Phone number",
type: UiTextTypeEnum.Info,
id: 9999,
},
},
- messages: [],
- meta: {},
}
const combinations = {
@@ -154,6 +159,10 @@ const combinations = {
idenfier_first_and_oidc: [identifierFirst, oidc],
}
+const wrapper = ({ children }: PropsWithChildren) => (
+ {children}
+)
+
for (const flowType of [
FlowType.Login,
FlowType.Registration,
@@ -172,11 +181,15 @@ for (const flowType of [
for (const [key, value] of Object.entries(combinations)) {
describe("combination=" + key, () => {
test("constructCardHeaderText", () => {
- const res = constructCardHeaderText(
- Array.isArray(value) ? value : [value],
- opts,
+ const res = renderHook(
+ () =>
+ useCardHeaderText(
+ Array.isArray(value) ? value : [value],
+ opts,
+ ),
+ { wrapper },
)
- expect(res).toMatchSnapshot()
+ expect(res.result.current).toMatchSnapshot()
})
})
}
diff --git a/packages/elements-react/src/theme/default/utils/constructCardHeader.ts b/packages/elements-react/src/theme/default/utils/constructCardHeader.ts
index 5f07b1e7e..94059f367 100644
--- a/packages/elements-react/src/theme/default/utils/constructCardHeader.ts
+++ b/packages/elements-react/src/theme/default/utils/constructCardHeader.ts
@@ -2,15 +2,16 @@
// SPDX-License-Identifier: Apache-2.0
import { FlowType, isUiNodeInputAttributes, UiNode } from "@ory/client-fetch"
+import { useIntl } from "react-intl"
-function joinWithCommaOr(list: string[]): string {
+function joinWithCommaOr(list: string[], orText = "or"): string {
if (list.length === 0) {
return "."
} else if (list.length === 1) {
- return list[0] + "."
+ return list[0]
} else {
const last = list.pop()
- return `${list.join(", ")} or ${last}.`
+ return `${list.join(", ")} ${orText} ${last}`
}
}
@@ -46,27 +47,38 @@ type opts =
* @param opts - can be a flow object, only needed for the refresh login flow
* @returns a title and a description for the card header
*/
-export function constructCardHeaderText(
+export function useCardHeaderText(
nodes: UiNode[],
opts: opts,
): { title: string; description: string } {
+ const intl = useIntl()
switch (opts.flowType) {
case FlowType.Recovery:
return {
- title: "Recover your account",
- description:
- "Enter the email address associated with your account to receive a one-time access code",
+ title: intl.formatMessage({
+ id: "recovery.title",
+ }),
+ description: intl.formatMessage({
+ id: "recovery.subtitle",
+ }),
}
case FlowType.Settings:
return {
- title: "Update your account",
- description: "Update your account settings",
+ title: intl.formatMessage({
+ id: "settings.title",
+ }),
+ description: intl.formatMessage({
+ id: "settings.subtitle",
+ }),
}
case FlowType.Verification:
return {
- title: "Verify your account",
- description:
- "Enter the email address associated with your account to verify it",
+ title: intl.formatMessage({
+ id: "verification.title",
+ }),
+ description: intl.formatMessage({
+ id: "verification.subtitle",
+ }),
}
}
@@ -75,26 +87,43 @@ export function constructCardHeaderText(
if (nodes.find((node) => node.group === "password")) {
switch (opts.flowType) {
case FlowType.Registration:
- parts.push(`your email and a password`)
+ parts.push(
+ intl.formatMessage(
+ { id: "card.header.parts.password.registration" },
+ // TODO: make this generic for other labels
+ { identifierLabel: "email" },
+ ),
+ )
break
default:
- parts.push(`your email and password`)
+ parts.push(
+ intl.formatMessage(
+ { id: "card.header.parts.password.login" },
+ // TODO: make this generic for other labels
+ { identifierLabel: "email" },
+ ),
+ )
}
}
+
if (nodes.find((node) => node.group === "oidc")) {
- parts.push(`a social provider`)
+ parts.push(
+ intl.formatMessage({
+ id: "card.header.parts.oidc",
+ }),
+ )
}
if (nodes.find((node) => node.group === "code")) {
- parts.push(`a code sent to your email`)
+ parts.push(intl.formatMessage({ id: "card.header.parts.code" }))
}
if (nodes.find((node) => node.group === "passkey")) {
- parts.push(`a Passkey`)
+ parts.push(intl.formatMessage({ id: "card.header.parts.passkey" }))
}
if (nodes.find((node) => node.group === "webauthn")) {
- parts.push(`a security key`)
+ parts.push(intl.formatMessage({ id: "card.header.parts.webauthn" }))
}
if (nodes.find((node) => node.group === "identifier_first")) {
@@ -106,7 +135,16 @@ export function constructCardHeaderText(
)
if (identifier) {
- parts.push(`your ${identifier.meta.label?.text}`)
+ parts.push(
+ intl.formatMessage(
+ {
+ id: "card.header.parts.identifier-first",
+ },
+ {
+ identifierLabel: identifier.meta.label?.text,
+ },
+ ),
+ )
}
}
@@ -114,20 +152,57 @@ export function constructCardHeaderText(
case FlowType.Login:
if (opts.flow.refresh) {
return {
- title: "Reauthenticate",
- description: "Confirm your identity with " + joinWithCommaOr(parts),
+ title: intl.formatMessage({
+ id: "login.title-refresh",
+ }),
+ description: intl.formatMessage(
+ {
+ id: "login.subtitle-refresh",
+ },
+ {
+ parts: joinWithCommaOr(parts),
+ },
+ ),
}
}
return {
- title: "Sign in",
+ title: intl.formatMessage({
+ id: "login.title",
+ }),
description:
- parts.length > 0 ? "Sign in with " + joinWithCommaOr(parts) : "",
+ parts.length > 0
+ ? intl.formatMessage(
+ {
+ id: "login.subtitle",
+ },
+ {
+ parts: joinWithCommaOr(
+ parts,
+ intl.formatMessage({ id: "misc.or" }),
+ ),
+ },
+ )
+ : "",
}
case FlowType.Registration:
return {
- title: "Sign up",
+ title: intl.formatMessage({
+ id: "registration.title",
+ }),
description:
- parts.length > 0 ? "Sign up with " + joinWithCommaOr(parts) : "",
+ parts.length > 0
+ ? intl.formatMessage(
+ {
+ id: "registration.subtitle",
+ },
+ {
+ parts: joinWithCommaOr(
+ parts,
+ intl.formatMessage({ id: "misc.or" }),
+ ),
+ },
+ )
+ : "",
}
}
diff --git a/src/locales/en.json b/src/locales/en.json
index e3f2430f6..05d2bb699 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -192,4 +192,4 @@
"verification.registration-button": "Sign up",
"verification.registration-label": "Don't have an account?",
"verification.title": "Verify your account"
-}
\ No newline at end of file
+}