Skip to content

🐛 Fixed missing favicon and apple-touch-icon in React admin#27528

Merged
jonatansberg merged 2 commits intoTryGhost:mainfrom
leafwind:fix/react-admin-missing-apple-touch-icon
Apr 29, 2026
Merged

🐛 Fixed missing favicon and apple-touch-icon in React admin#27528
jonatansberg merged 2 commits intoTryGhost:mainfrom
leafwind:fix/react-admin-missing-apple-touch-icon

Conversation

@leafwind
Copy link
Copy Markdown
Contributor

@leafwind leafwind commented Apr 23, 2026

🐛 Fixed missing favicon and apple-touch-icon in React admin

iOS Safari falls back to showing the first letter of the page title ("G") instead of the Ghost logo when adding the admin to an iOS home screen. The apple-touch-icon link was lost during the Ember→React admin migration — the emberAssetsPlugin only injects CSS, JS, and config meta tags, not icon link tags.

  • I've read and followed the Contributor Guide
  • I've explained my change
  • I've written an automated test to prove my change works

Note

Low Risk
Small, static HTML change plus a unit test; no runtime logic or security-sensitive code paths affected.

Overview
Restores iOS home-screen icon support for the React admin by adding an apple-touch-icon link to apps/admin/index.html.

Adds a Vitest check (src/index-html.test.ts) to ensure the tag exists and that its href is relative (not /...) so admin installs served from subdirectories don’t break.

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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 23, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a <link rel="apple-touch-icon"> element to the <head> of apps/admin/index.html pointing to assets/img/apple-touch-icon.png. Adds apps/admin/src/index-html.test.ts, a Vitest test that loads the HTML as raw text, locates the <link rel="apple-touch-icon"> element, extracts its href, verifies the href exists, strips any query string, asserts the path is relative (does not start with /) and contains apple-touch-icon.png, and checks the resolved file exists under ../public.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding missing favicon and apple-touch-icon support to the React admin, which directly matches the pull request objectives.
Description check ✅ Passed The description is clearly related to the changeset, explaining the iOS Safari fallback issue, the lost apple-touch-icon link during migration, and the solution provided in the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 and usage tips.

@leafwind leafwind changed the title Fixed missing favicon and apple-touch-icon in React admin 🐛 Fixed missing favicon and apple-touch-icon in React admin Apr 23, 2026
@leafwind leafwind force-pushed the fix/react-admin-missing-apple-touch-icon branch 3 times, most recently from d232149 to f30b7bd Compare April 23, 2026 15:31
@cursor
Copy link
Copy Markdown

cursor Bot commented Apr 23, 2026

You have used all of your free Bugbot PR reviews.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

@9larsons 9larsons requested a review from jonatansberg April 23, 2026 18:39
@leafwind leafwind force-pushed the fix/react-admin-missing-apple-touch-icon branch from f30b7bd to 0a0dd9f Compare April 24, 2026 00:58
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
apps/admin/src/index-html.test.ts (2)

6-8: Regex is sensitive to attribute order/quoting.

The pattern only matches when rel="apple-touch-icon" appears before href, both use double quotes, and there's no intervening whitespace variation. A benign edit to index.html (e.g., reordering attributes to href="..." rel="apple-touch-icon", using single quotes, or adding sizes/type before href) would silently null out appleTouchIconHref, causing tests 2 and 3 to fail for reasons unrelated to the actual bug this suite is guarding against. Consider parsing with a lightweight HTML parser (e.g., node-html-parser) or splitting into two regex passes: locate the <link ... rel="apple-touch-icon" ...> tag first, then extract href from it independently of order.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/admin/src/index-html.test.ts` around lines 6 - 8, The current extraction
for appleTouchIconHref (headContent and appleTouchIconHref) is brittle because
the regex assumes rel appears before href and uses double quotes; update the
logic to be order- and quote-agnostic by either using a lightweight HTML parser
(e.g., node-html-parser) to parse headContent and query for the <link
rel="apple-touch-icon"> element then read its href, or perform two robust regex
passes: first match the full <link ...> tag containing
rel=('|")apple-touch-icon\1 (searching within headContent) and then extract the
href attribute from that matched tag regardless of attribute order/quoting;
replace the current single regex that sets appleTouchIconHref accordingly.

15-20: Also guard against protocol-absolute URLs.

The "relative path" assertion only rejects paths starting with /. An href like https://cdn.example.com/apple-touch-icon.png or //cdn.example.com/... would still pass, yet would equally break subdirectory installs (and the fs.existsSync check in the next test would then fail confusingly). A small tightening keeps the intent explicit.

🧪 Proposed tightening
-        expect(filePath).not.toMatch(/^\//);
+        expect(filePath).not.toMatch(/^\/|^[a-z]+:\/\//i);
         expect(filePath).toContain('apple-touch-icon.png');
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/admin/src/index-html.test.ts` around lines 15 - 20, The test "href is a
relative path (absolute paths break subdirectory installs)" currently only
rejects leading slashes; update the assertions around appleTouchIconHref in that
test to also reject protocol-absolute and absolute URLs (e.g., starting with
'//' or a scheme like 'http:'/'https:'). Locate the test block containing the
variable appleTouchIconHref and replace or add the regex check so filePath (or
appleTouchIconHref) does not match patterns like
/^\/|^\/\/|^[a-zA-Z][a-zA-Z0-9+.-]*:/. This will ensure only true relative paths
are allowed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/admin/src/index-html.test.ts`:
- Around line 6-8: The current extraction for appleTouchIconHref (headContent
and appleTouchIconHref) is brittle because the regex assumes rel appears before
href and uses double quotes; update the logic to be order- and quote-agnostic by
either using a lightweight HTML parser (e.g., node-html-parser) to parse
headContent and query for the <link rel="apple-touch-icon"> element then read
its href, or perform two robust regex passes: first match the full <link ...>
tag containing rel=('|")apple-touch-icon\1 (searching within headContent) and
then extract the href attribute from that matched tag regardless of attribute
order/quoting; replace the current single regex that sets appleTouchIconHref
accordingly.
- Around line 15-20: The test "href is a relative path (absolute paths break
subdirectory installs)" currently only rejects leading slashes; update the
assertions around appleTouchIconHref in that test to also reject
protocol-absolute and absolute URLs (e.g., starting with '//' or a scheme like
'http:'/'https:'). Locate the test block containing the variable
appleTouchIconHref and replace or add the regex check so filePath (or
appleTouchIconHref) does not match patterns like
/^\/|^\/\/|^[a-zA-Z][a-zA-Z0-9+.-]*:/. This will ensure only true relative paths
are allowed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f6813bed-9c3f-4e8c-bdb0-abf0ec05ae83

📥 Commits

Reviewing files that changed from the base of the PR and between f30b7bd and 0a0dd9f.

⛔ Files ignored due to path filters (1)
  • apps/admin/public/assets/img/apple-touch-icon.png is excluded by !**/*.png
📒 Files selected for processing (2)
  • apps/admin/index.html
  • apps/admin/src/index-html.test.ts
✅ Files skipped from review due to trivial changes (1)
  • apps/admin/index.html

@sonarqubecloud
Copy link
Copy Markdown

@jonatansberg jonatansberg enabled auto-merge (squash) April 29, 2026 12:56
@jonatansberg jonatansberg disabled auto-merge April 29, 2026 12:56
@jonatansberg jonatansberg force-pushed the fix/react-admin-missing-apple-touch-icon branch from d48ba85 to beb5168 Compare April 29, 2026 12:58
leafwind and others added 2 commits April 29, 2026 14:59
iOS Safari falls back to the page title's first letter ("G") instead of
the Ghost logo when saving the admin as a home screen shortcut. The
apple-touch-icon link was lost during the Ember→React admin migration —
emberAssetsPlugin only injects CSS, JS, and config meta tags, not icon
link tags.
Moved the remaining admin favicon asset into the React admin public assets so the React entrypoint owns the icon metadata it serves.
@jonatansberg jonatansberg enabled auto-merge (squash) April 29, 2026 12:59
@jonatansberg
Copy link
Copy Markdown
Member

@leafwind thank you for identifying this and creating a PR! I went ahead and moved the old favicon as well.

@jonatansberg jonatansberg force-pushed the fix/react-admin-missing-apple-touch-icon branch from beb5168 to 598e44a Compare April 29, 2026 13:00
@leafwind
Copy link
Copy Markdown
Contributor Author

@leafwind thank you for identifying this and creating a PR! I went ahead and moved the old favicon as well.

@jonatansberg I appreciate your help (because I am not familiar with the folder structure), thanks!

@jonatansberg jonatansberg merged commit 8ecd144 into TryGhost:main Apr 29, 2026
41 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants