Use one verb per action in the English UI: sign in, sign out, create account
CI / full-gate (push) Successful in 2m39s

This commit is contained in:
2026-08-05 00:34:05 +02:00
parent 46548ae758
commit 34b668d49f
7 changed files with 25 additions and 9 deletions
+1 -1
View File
@@ -122,7 +122,7 @@ export function firstRunBanner(opts: { appUrl: string; email: string; password:
const rule = "─".repeat(58);
return [
`${rule}`,
`│ Plainpages is ready — log in at ${opts.appUrl}`,
`│ Plainpages is ready — sign in at ${opts.appUrl}`,
`│ email: ${opts.email}`,
`│ password: ${opts.password}`,
`│ ⚠ Demo admin credentials — change them before production.`,
+10
View File
@@ -24,6 +24,16 @@ test("the shipped core catalogs load and agree key for key", async () => {
assert.ok(loaded.available.includes("sv-SE"));
assert.deepEqual([...loaded.available].sort(), loaded.available); // sorted, so "sv" resolves deterministically
assert.ok(Object.keys(loaded.core.get("en-US") ?? {}).length > 20);
// One verb per action: sign in / sign out / create account. Two spellings for one button ("Log in"
// on the landing, "Sign in" in the sidebar) read as two different things. Nouns ("a sign-in error")
// are fine — only the competing verbs are out. AGENTS.md → Rules.
const competing = /\b(log[\s-]?in|log[\s-]?out|sign[\s-]?up)\b/i;
const offenders = Object.entries(loaded.core.get("en-US") ?? {})
.map(([key, message]) => [key, typeof message === "string" ? message : Object.values(message).join(" ")] as const)
.filter(([, text]) => competing.test(text))
.map(([key, text]) => `${key}: ${text}`);
assert.deepEqual(offenders, []);
});
test("a plugin's catalogs load under its id and may cover fewer locales than the host", async () => {
+3 -3
View File
@@ -108,7 +108,7 @@ const messages = {
// "Email" on the login form and "First name" on a registration form with that trait, so it can
// only be translated per field (auth.field.* above), never per id.
"kratos.1010022": "Sign in with password",
"kratos.1040001": "Sign up",
"kratos.1040001": "Create account",
"kratos.1060003":
"An email containing a recovery code has been sent to the email address you provided. If you have not received an email, check the spelling of the address and make sure to use the address you registered with.",
"kratos.1070008": "Resend code",
@@ -127,7 +127,7 @@ const messages = {
"landing.lead":
"{{brand}} is a self-hostable foundation for admin and operational UIs — sign-in, a config-driven menu, and a server-rendered, zero-JS design system. You add the domain-specific screens by dropping in plugin folders.",
"landing.register": "Create account",
"landing.signIn": "Log in",
"landing.signIn": "Sign in",
"landing.title": "Operational web apps, without the boilerplate.",
"locale.label": "Language",
@@ -137,7 +137,7 @@ const messages = {
"oauth.consentExpired": "This authorization request has expired. Please start again from the application you were signing in to.",
"oauth.loginExpired": "This sign-in request has expired. Please start again from the application you were signing in to.",
"oauth.logoutExpired": "This logout request has expired. Please start again from the application you were signing out of.",
"oauth.logoutExpired": "This sign-out request has expired. Please start again from the application you were signing out of.",
"pagination.go": "Go",
"pagination.label": "Pagination",