Add mobile web app support (Add to Home Screen)#91
Conversation
Enable Press This to work as a standalone mobile web app via Add to Home Screen on Android and iOS. Adds Web App Manifest with Share Target API support, app icons, mobile web app meta tags, and standalone mode UI handling. Closes #2 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds Progressive Web App (Add to Home Screen) support for Press This, including a web app manifest endpoint and UI behavior tweaks for standalone display mode.
Changes:
- Serve a Web App Manifest via a new public REST endpoint, including Share Target support.
- Add standalone-mode behavior adjustments (redirect behavior + menu items).
- Add mobile web app meta tags and icon/manifest links in the Press This HTML head.
Reviewed changes
Copilot reviewed 5 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/components/PressThisEditor.js | Detects standalone mode to adjust redirect behavior. |
| src/components/Header.js | Adds standalone-only menu items and standalone detection. |
| press-this-plugin.php | Registers a new REST route and returns the manifest JSON. |
| includes/class-press-this-assets.php | Syncs script dependencies by adding wp-keyboard-shortcuts. |
| class-wp-press-this-plugin.php | Injects mobile web app meta tags and manifest/icon links. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Set Content-Type to application/manifest+json per W3C spec. Localize the app name in both the manifest endpoint and the apple-mobile-web-app-title meta tag for translation support. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 8 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return ( | ||
| window.matchMedia( '(display-mode: standalone)' ).matches || | ||
| window.navigator.standalone === true |
| () => | ||
| window.matchMedia( '(display-mode: standalone)' ).matches || | ||
| window.navigator.standalone === true, |
| { isStandalone && ( | ||
| <> | ||
| <MenuItem | ||
| href={ siteUrl } | ||
| onClick={ onClose } | ||
| > | ||
| { __( | ||
| 'View Site', | ||
| 'press-this' | ||
| ) } | ||
| </MenuItem> | ||
| <MenuItem | ||
| onClick={ () => { | ||
| // Reload without query params for a blank post. | ||
| window.location.href = | ||
| window.location.pathname; | ||
| onClose(); | ||
| } } | ||
| > | ||
| { __( | ||
| 'New Post', | ||
| 'press-this' | ||
| ) } | ||
| </MenuItem> | ||
| </> | ||
| ) } |
| function performSafeRedirect( url, inParentWindow = false ) { | ||
| const safeUrl = safeRedirect( url ); | ||
|
|
||
| // In standalone mode there's no opener window, so always redirect self. | ||
| if ( isStandaloneMode() ) { | ||
| window.location.href = safeUrl; | ||
| return; | ||
| } |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 10 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| register_rest_route( | ||
| 'press-this/v1', | ||
| '/manifest', | ||
| array( | ||
| 'methods' => WP_REST_Server::READABLE, | ||
| 'callback' => 'press_this_rest_manifest', | ||
| 'permission_callback' => '__return_true', | ||
| ) | ||
| ); |
There was a problem hiding this comment.
press_this_register_rest_routes() uses WP_REST_Server::READABLE for the new /manifest route, but other routes in the same function use string literals (e.g., 'POST'). Please make the methods style consistent within this file (either use 'GET' here, or convert the other routes to WP_REST_Server constants).
| // Detect standalone display mode (added to home screen). | ||
| const isStandalone = useMemo( | ||
| () => | ||
| ( typeof window.matchMedia === 'function' && | ||
| window.matchMedia( '(display-mode: standalone)' ).matches ) || | ||
| window.navigator.standalone === true, | ||
| [] | ||
| ); |
There was a problem hiding this comment.
Standalone-mode detection logic is duplicated in both Header and PressThisEditor (matchMedia (display-mode: standalone) + navigator.standalone). Consider extracting this into a shared utility so the detection stays consistent and future changes only need to be made in one place.
| function isStandaloneMode() { | ||
| return ( | ||
| ( typeof window.matchMedia === 'function' && | ||
| window.matchMedia( '(display-mode: standalone)' ).matches ) || | ||
| window.navigator.standalone === true | ||
| ); |
There was a problem hiding this comment.
Standalone-mode detection logic is duplicated (also implemented in Header.js). Consider reusing a shared helper (e.g., in src/utils) so there’s a single source of truth for standalone detection.
Summary
Enables Press This to work as a standalone mobile web app that can be added to the home screen on Android and iOS. Implements the core features from #2 (originally WordPress core Trac #33195).
/press-this/v1/manifest) with Share Target API support (Android)mobile-web-app-capable,apple-mobile-web-app-capable,theme-color, etc.)window.close()in redirects, add "View Site" and "New Post" menu itemsShare Target
The manifest
share_targetreuses Press This's existing GET params (?u=...&t=...), so sharing a URL from another Android app opens Press This with the URL pre-filled — no editor changes needed.Future enhancements
These are out of scope for this PR but documented for future work:
apple-touch-startup-imagetags per device resolutionPOST+multipart/form-dataTest plan
<head>/wp-json/press-this/v1/manifest— confirm valid JSON with correct dynamic URLswindow.close()