diff --git a/aggregator.html b/aggregator.html
index c3c422bf..20125b19 100644
--- a/aggregator.html
+++ b/aggregator.html
@@ -33,7 +33,8 @@
const id = params.get('id');
const total = parseInt(params.get('n') || '0');
const index = parseInt(params.get('i') || '-1');
- const data = params.get('d');
+ // Keep the chunk percent-encoded so URI delimiters remain part of the settings payload.
+ const data = hash.match(/(?:^|&)d=([^&]*)/)?.[1];
const app = document.getElementById('app');
diff --git a/test/browser-apps/pages/browser-smoke.test.ts b/test/browser-apps/pages/browser-smoke.test.ts
index 2c300667..3be1286d 100644
--- a/test/browser-apps/pages/browser-smoke.test.ts
+++ b/test/browser-apps/pages/browser-smoke.test.ts
@@ -30,12 +30,15 @@ Deno.test({
const aggregator = await browser.newPage();
const assertNoAggregatorFailures = observePageFailures(aggregator);
const assertNoAggregatorNetworkFailures = observeNetworkFailures(aggregator);
- await aggregator.goto(new URL("aggregator.html#id=pages-smoke&n=2&i=0&d=first-", server.baseUrl).href);
+ await aggregator.goto(new URL("aggregator.html#id=pages-smoke&n=2&i=0&d=before%2", server.baseUrl).href);
await aggregator.getByText("1 / 2 Loaded", { exact: true }).waitFor();
- await aggregator.goto(new URL("aggregator.html#id=pages-smoke&n=2&i=1&d=second", server.baseUrl).href);
+ await aggregator.goto(
+ new URL("aggregator.html#id=pages-smoke&n=2&i=1&d=3after%26amp%2Bplus%25percent", server.baseUrl)
+ .href
+ );
assertEquals(
await aggregator.getByRole("link", { name: "Open Obsidian to complete setup" }).getAttribute("href"),
- "obsidian://setuplivesync?settingsQR=first-second"
+ "obsidian://setuplivesync?settingsQR=before%23after%26amp%2Bplus%25percent"
);
assertNoAggregatorFailures();
assertNoAggregatorNetworkFailures();
diff --git a/updates.md b/updates.md
index d476c1d5..e4e701fc 100644
--- a/updates.md
+++ b/updates.md
@@ -12,6 +12,12 @@ Earlier releases remain available in the 0.25 release history and the legacy rel
## Unreleased
+### Setup and compatibility
+
+#### Fixed
+
+- Multi-part settings QR codes now preserve special characters in passwords, passphrases, and other settings.
+
## 1.0.6
6th August, 2026