Skip to content

fix(web): add web app manifest so installed app keeps its scope#4306

Open
Albro3459 wants to merge 4 commits into
pingdotgg:mainfrom
Albro3459:fix/web-manifest-scope
Open

fix(web): add web app manifest so installed app keeps its scope#4306
Albro3459 wants to merge 4 commits into
pingdotgg:mainfrom
Albro3459:fix/web-manifest-scope

Conversation

@Albro3459

@Albro3459 Albro3459 commented Jul 22, 2026

Copy link
Copy Markdown

What Changed

  • Adds apps/web/public/manifest.webmanifest declaring scope and start_url at the origin root, with display: standalone.
  • Adds <link rel="manifest" href="/manifest.webmanifest" /> to apps/web/index.html.

Two files, one line of HTML. No new dependencies, no service worker, no new binary assets, no runtime logic, no CSS changes.

Why

Fixes #4305.

apps/web currently ships no web app manifest, so the scope member is never declared. With no scope, iOS infers the navigation scope of an installed Home Screen app from whichever URL was saved.

The app redirects the origin root to the last-opened thread, so the URL captured by "Add to Home Screen" is usually /<environmentId>/<threadId>. Scope collapses to that single thread path, and every subsequent navigation is treated as out of scope and handed off to an in-app browser view, ending the standalone session.

Declaring scope: "/" makes every route on the origin part of the app.

Why the icons reuse existing filenames

scripts/lib/brand-assets.ts swaps web icons by target filename per release channel (nightly-web-apple-touch-180.png and t3-black-web-apple-touch-180.png both land as apple-touch-icon.png).

The manifest therefore references the existing apple-touch-icon.png and favicon-32x32.png rather than adding a new icon asset, so publish-time brand overrides keep applying and nightly builds do not ship the production mark.

Testing

Verified against a real t3 serve build (0.0.29-nightly.20260722.878) served over HTTPS, on iOS 26.5 / Safari.

Server side:

$ curl -s -o /dev/null -w '%{http_code} %{content_type}\n' \
    http://127.0.0.1:3773/manifest.webmanifest
200 application/manifest+json

Mime.getType() in apps/server/src/http.ts resolves .webmanifest correctly, so no MIME handling changes are needed.

Device: added to the Home Screen from a deep-linked thread URL (/<environmentId>/<threadId>), the case that previously broke. Before the change, navigating to another thread left standalone mode and opened an in-app browser view. After the change, navigation stays inside the installed app across threads and Settings.

Deliberately out of scope

  • No Android/Chrome installability. The largest existing icon is 180x180 and Chrome wants 192 and 512, but adding icon assets is a separate change.
  • No apple-mobile-web-app-* meta tags. Safari 17+ honors display: standalone from the manifest directly.
  • No safe-area or app-shell CSS, no push notifications.

Note

Low Risk
Static manifest plus one HTML link; no auth, data, or runtime logic changes.

Overview
Fixes installed iOS Home Screen behavior when the save URL is a deep-linked thread: without a declared scope, Safari narrows the app to that path and later navigation opens in an in-app browser.

This PR adds manifest.webmanifest with id, start_url, and scope set to /, display: standalone, dark theme colors, and icons pointing at existing favicon-32x32.png and apple-touch-icon.png (so release-channel icon swaps keep working). index.html gains <link rel="manifest" href="/manifest.webmanifest" />.

Reviewed by Cursor Bugbot for commit 5449f71. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add web app manifest to preserve scope when app is installed

Adds manifest.webmanifest and links it in index.html. The manifest sets id, start_url, and scope to /, uses standalone display mode, and declares PNG icons at 32×32 and 180×180 with dark theme colors.

Macroscope summarized 5449f71.

apps/web ships no manifest, so iOS infers the navigation scope of an
installed home screen app from whichever URL was saved. Saving a deep
link collapses scope to that single path, and every other route is
treated as out of scope and handed off to an in-app browser view.

Declare scope and start_url at the origin root with display standalone.

Icons reuse the existing asset filenames so the publish-time brand
overrides in scripts/lib/brand-assets.ts keep applying per release
channel.

Fixes pingdotgg#4305
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ca9a4f36-0365-4214-b29d-c4d9b2a9b7ab

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the vouch:unvouched PR author is not yet trusted in the VOUCHED list. label Jul 22, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Jul 22, 2026
@macroscopeapp

macroscopeapp Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved

Adds a static web app manifest file for PWA support. This is a simple configuration-only change with no runtime code modifications - just a JSON file specifying display properties and existing icon references.

You can customize Macroscope's approvability policy. Learn more.

@github-actions github-actions Bot added the size:S 10-29 changed lines (additions + deletions). label Jul 22, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 3cbb8eb. Configure here.

Comment thread apps/web/public/manifest.webmanifest Outdated
APP_DISPLAY_NAME resolves per channel ("T3 Code (Nightly)", "(Alpha)",
"(Dev)") from the hosted channel or the desktop bridge, and
DocumentTitleSync keeps document.title in sync with it at runtime.

A static name/short_name in public/ cannot follow that, so a nightly
install would show the production label next to nightly-branded icons.
Making the manifest channel-aware would require generating it at build
time, since Vite does not template files in public/.

name and short_name are optional, so omitting them lets the Home Screen
label fall back to document.title, which is already correct per channel.
@macroscopeapp
macroscopeapp Bot dismissed their stale review July 22, 2026 22:22

Dismissing prior approval to re-evaluate 1d66bcb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Installed home screen web app drops out to Safari when navigating between chats

1 participant