PWA parity and analytics (migration 7/8) - #695
Conversation
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
| <meta name="twitter:image" content="/assets/images/logo-loading.png"> | ||
|
|
||
| <meta property="og:title" content="Angular 2 HN"/> | ||
| <meta property="og:type" content="website"/> | ||
| <meta property="og:url" content="https://angular2-hn.firebaseapp.com/"/> | ||
| <meta property="og:image" content="/assets/images/logo-loading.png"/> |
There was a problem hiding this comment.
🟡 Share preview image points to a missing file
twitter:image and og:image both reference /assets/images/logo-loading.png, but no such file exists under public/assets/images (only cog.svg, logo-header.png, logo.svg). Social and share previews resolve to a 404.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Preexisting, not introduced here — logo-loading.png was deleted upstream in b954b67 ("replace images with svgs") while the meta tags kept pointing at it, so src/index.html on master 404s the same way. This PR carried the tags over verbatim as part of the metadata port. Leaving it alone rather than silently repointing the share image at logo.svg (most crawlers won't render SVG previews, so that's a content decision, not a port fix) — happy to change it if you'd rather have working previews.
| if (location.pathname === '/') { | ||
| return; | ||
| } | ||
|
|
||
| const page = `${location.pathname}${location.search}`; | ||
| window.ga?.('set', 'page', page); | ||
| window.ga?.('send', 'pageview'); |
There was a problem hiding this comment.
📝 Info: Page-view skip depends on '/' redirect path
usePageViews suppresses the / view so the root redirect to /news/1 does not double-count, and the GA snippet no longer sends an initial view. Correct only while the sole redirect origin stays exactly /.
Was this helpful? React with 👍 or 👎 to provide feedback.
e1d0bfe to
391655a
Compare
| createRoot(document.getElementById('root')!).render( | ||
| registerSW({ immediate: true }); | ||
|
|
||
| createRoot(document.getElementById('content')!).render( |
There was a problem hiding this comment.
Co-Authored-By: Charity Quinn <charity.quinn@cognition.ai>
Co-Authored-By: Charity Quinn <charity.quinn@cognition.ai>
247e4b0 to
bf01639
Compare
Summary
Stacked on #694. Restores the two things the React build was missing versus Angular: the service worker / installability metadata, and page-view tracking.
Service worker —
vite-plugin-pwa@0.20.5(Workbox) replacesServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }). The config mirrorsngsw-config.json's two asset groups: precache the app shell (js,css,html,ico+manifest.json, matching theprefetchgroup) and runtime-cache/assets/**(thelazygroup).navigateFallback: '/index.html'keeps deep links like/item/123working offline.manifest: false—public/manifest.jsonstays the single source of truth instead of generating a second one. No runtime caching fornode-hnapi.herokuapp.com; Angular didn't cache API responses either.devOptionsstays disabled and registration is manual (registerSW({ immediate: true })), so the SW is production-only as before.The assets route uses
StaleWhileRevalidate, notCacheFirst. Angular's asset group wasinstallMode: lazy+updateMode: prefetch— fetch on first request, but refresh cached copies when a new version activates — andpublic/assets/*filenames aren't content-hashed, soCacheFirstwould serve a changed logo from cache forever. Revisioned precaching is the closer analogue ofupdateMode: prefetch, but it would download every icon at install time, which is exactly whatinstallMode: lazyavoided;StaleWhileRevalidatekeeps the lazy fetch and lets a stale asset heal on the next load.index.html— carries over the full metadata block fromsrc/index.html: description, twitter/og cards,theme-color#b92b27(the Angular index also had a stray CLI-generated#1976d2; dropped in favor of the one matching the manifest), msapplication + apple-mobile-web-app metas, mask-icon, favicons and apple-touch-icons, with paths made root-absolute for Vite'spublic/. The skip-nav link and<noscript>message are kept; the.app-loaderspinner is not — React mounts into that container, so a pre-boot spinner would never be removed.Analytics — the
analytics.jssnippet andga('create', 'UA-66348622-3', 'auto')return toindex.html, andapp.component.ts'sNavigationEndsubscription becomesusePageViews(), an effect onuseLocation().urlAfterRedirectsmeant the post-redirect URL, so the hook skips/— otherwise the/→/news/1redirect would report a phantom/view.gais declared as a narrow optional global and called throughwindow.ga?.(...), so builds without the snippet don't throw.Verified:
yarn react:buildpasses;sw.jsactivates on the preview server with the expected precache list and aStaleWhileRevalidatestrategy registered for the assets route, an offline hard-reload of/news/1still renders the shell, and stubbingwindow.gaon a cold load of/records exactly['set','page','/news/1']+['send','pageview'].Devin-Org: engineering
Link to Devin session: https://app.devin.ai/sessions/1ff25c6cf2f949458f82cc596fc79c65
Requested by: @charityquinn-cognition