eleven / messenger Public

web+home: "backup" copy becomes sign-in language (#1259)

The audit's copy sweep: the product's model is "you sign in" (the anchor
model), but several surfaces still said "backup" — the retired framing.

- adddevice.js + the menu: "Add a device or back up" → "Add a device";
  the enrol button "Back up" → "Sign in with Eleven"; the note frames the
  one-time link as "a way back in", not "your backup".
- shell.js sign-out-of-only-device dialog: "Save a backup link first" →
  "Save a way back in first" (button to match).
- home: anchors.go's last-anchor refusal drops the dangling "or delete
  the backup instead" (no such surfaced action); merge.go's precondition
  refusal says "still has spaces saved to it"; home.js's combine
  fallbacks say "spaces list" (matching the busy line beside them).

Internal identifiers (backup.js module, deferBackupReminders verb, native
enum cases) deliberately keep their names — code, not copy.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Paul Campbell 6f45a3eaaccd7be5c49b20373f66eace6c30a7cb parent 04c4698
7 files changed, +21 −16
  • changelog/2026-07-22-sign-in-not-backup.md +5 −0
  • home/anchors.go +1 −1
  • home/merge.go +2 −2
  • home/web/static/home.js +2 −2
  • web/pages/index.html +1 −1
  • web/static/adddevice.js +6 −6
  • web/static/shell.js +4 −4
diff --git a/changelog/2026-07-22-sign-in-not-backup.md b/changelog/2026-07-22-sign-in-not-backup.md
new file mode 100644
index 0000000..e45bba1
--- /dev/null
+++ b/changelog/2026-07-22-sign-in-not-backup.md
@@ -0,0 +1,5 @@
+🤖 Clearer words for keeping your access safe. The old "back up" language is
+gone: the menu now says "Add a device", the add-a-device card offers "Sign in
+with Eleven" alongside saving the one-time link, and signing out of your only
+device asks you to save a way back in first. Same protections, said the way
+they work — you sign in; nothing to file away.
diff --git a/home/anchors.go b/home/anchors.go
index 68852ec..6e07407 100644
--- a/home/anchors.go
+++ b/home/anchors.go
@@ -110,7 +110,7 @@ func (s *Server) deleteAnchorHandler(w http.ResponseWriter, r *http.Request) {
return
}
if last {
- http.Error(w, "that's the last way into this account — add another way to sign in before removing it, or delete the backup instead", http.StatusConflict)
+ http.Error(w, "that's the last way into this account — add another way to sign in before removing it", http.StatusConflict)
return
}
if !deleted {
diff --git a/home/merge.go b/home/merge.go
index c5b4b65..5c46031 100644
--- a/home/merge.go
+++ b/home/merge.go
@@ -75,14 +75,14 @@ func (s *Server) mergeAccountHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, "db error", http.StatusInternalServerError)
return
} else if found {
- http.Error(w, "That account still holds a backup — move the spaces over first", http.StatusConflict)
+ http.Error(w, "That account still has spaces saved to it — move them over first", http.StatusConflict)
return
}
moved, err := s.store.mergeAccounts(survivor, absorbed)
if errors.Is(err, errAbsorbedHasBlob) {
// The store's belt caught a blob written between the check above and
// the merge.
- http.Error(w, "That account still holds a backup — move the spaces over first", http.StatusConflict)
+ http.Error(w, "That account still has spaces saved to it — move them over first", http.StatusConflict)
return
}
if err != nil {
diff --git a/home/web/static/home.js b/home/web/static/home.js
index bbfe0e8..42ff5f4 100644
--- a/home/web/static/home.js
+++ b/home/web/static/home.js
@@ -2366,7 +2366,7 @@ async function combineSkipYes() {
await deleteAbsorbedBlob();
combineFinish(0);
} catch (e) {
- combineStatus((e && e.message) || "Couldn’t clear the other account’s backup.", "error");
+ combineStatus((e && e.message) || "Couldn’t clear the other account’s spaces list.", "error");
} finally {
btn.disabled = false;
}
@@ -2382,7 +2382,7 @@ async function deleteAbsorbedBlob() {
}
const res = await fetch("/api/blob", { method: "DELETE", headers: { "X-Ceremony-Proof": combine.absorbedProof } });
if (!res.ok && res.status !== 404) {
- throw new Error(((await res.text().catch(() => "")) || "").trim() || "Couldn’t clear the other account’s backup.");
+ throw new Error(((await res.text().catch(() => "")) || "").trim() || "Couldn’t clear the other account’s spaces list.");
}
}
diff --git a/web/pages/index.html b/web/pages/index.html
index 983e565..8e10d19 100644
--- a/web/pages/index.html
+++ b/web/pages/index.html
@@ -152,7 +152,7 @@
<button class="menu-item" id="menu-apps" role="menuitem">Apps</button>
<button class="menu-item" id="menu-notif" role="menuitem">Notifications</button>
<button class="menu-item" id="menu-theme" role="menuitem">Theme</button>
- <button class="menu-item" id="menu-add-device" role="menuitem">Add a device / back up</button>
+ <button class="menu-item" id="menu-add-device" role="menuitem">Add a device</button>
<!-- Mac desktop browsers only (shell.js unhides): the one
platform with a scheme receiver today; iOS follows. -->
<button class="menu-item" id="menu-open-app" role="menuitem" hidden>Open in the Eleven app</button>
diff --git a/web/static/adddevice.js b/web/static/adddevice.js
index 6965fb1..34cc514 100644
--- a/web/static/adddevice.js
+++ b/web/static/adddevice.js
@@ -41,10 +41,10 @@ export async function addDevice() {
const backdrop = verbs.modal();
const card = backdrop.querySelector(".sheet");
const h = document.createElement("h2");
- h.textContent = "Add a device or back up";
+ h.textContent = "Add a device";
const note = document.createElement("p");
note.className = "sub";
- note.textContent = "Open this on another device to sign in there — or save it somewhere safe (like a password manager) as your backup: it's the only way back in if you lose this device. It works once, and anyone who uses it signs in as you.";
+ note.textContent = "Open this on another device to sign in there — or save it somewhere safe (like a password manager): it's a way back in if you lose this device. It works once, and anyone who uses it signs in as you.";
const qr = document.createElement("div");
qr.className = "qr-wrap";
try {
@@ -80,13 +80,13 @@ export async function addDevice() {
const row = document.createElement("div");
row.className = "row";
row.appendChild(copy);
- // A passkey backup is the one-tap alternative to saving the link: enrol (or
- // update) this instance with the home server. Only shown when a home server
- // is configured — launchEnrol is a no-op otherwise.
+ // Signing in with Eleven is the one-tap alternative to saving the link:
+ // enrol (or update) this instance with the home server. Only shown when a
+ // home server is configured — launchEnrol is a no-op otherwise.
if (window.__homeOrigin) {
const backup = document.createElement("button");
backup.className = "secondary";
- backup.textContent = "Back up";
+ backup.textContent = "Sign in with Eleven";
backup.onclick = () => {
backdrop.remove(); // web navigates same-tab; native/PWA opens a new context
launchEnrol(session);
diff --git a/web/static/shell.js b/web/static/shell.js
index 73b86f2..cea5a1e 100644
--- a/web/static/shell.js
+++ b/web/static/shell.js
@@ -8093,7 +8093,7 @@ async function leave() {
return;
}
- // Only device: warn hard and offer to save a backup link first.
+ // Only device: warn hard and offer a way back in first.
const backdrop = modal();
const card = backdrop.querySelector(".sheet");
const h = document.createElement("h2");
@@ -8101,7 +8101,7 @@ async function leave() {
const p = document.createElement("p");
p.className = "sub";
p.textContent =
- "Your chats are encrypted to a key that lives only on this device. Sign out and you'll lose access to them for good — there's no way to recover it. Save a backup link first so you can get back in.";
+ "Your chats are encrypted to a key that lives only on this device. Sign out and you'll lose access to them for good — there's no way to recover it. Save a way back in first.";
const foot = document.createElement("div");
foot.className = "sheet-foot";
const out = document.createElement("button");
@@ -8112,10 +8112,10 @@ async function leave() {
doSignout();
};
const backup = document.createElement("button");
- backup.textContent = "Save a backup first";
+ backup.textContent = "Save a way back in";
backup.onclick = () => {
backdrop.remove();
- addDevice(); // save that link, then sign out later if you still want to
+ addDevice(); // sign in with Eleven or save the link, then sign out later if you still want to
};
foot.appendChild(out);
foot.appendChild(backup);