Skip to content
Merged

pwa #73

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import type { Metadata } from 'next'
import Script from 'next/script'
import { Inter } from 'next/font/google'
import { LaunchGate } from '@/components/LaunchGate'
import { ServiceWorkerRegistrar } from '@/components/ServiceWorkerRegistrar'
import { PwaMetaTags } from '@/components/PwaMetaTags'
import './globals.css'

const inter = Inter({
Expand All @@ -20,6 +22,8 @@ export const metadata: Metadata = {
{ url: '/learn/favicon.ico', sizes: 'any' },
{ url: '/learn/favicon.svg', type: 'image/svg+xml' },
{ url: '/learn/favicon-96x96.png', sizes: '96x96', type: 'image/png' },
{ url: '/learn/favicon-192x192.png', sizes: '192x192', type: 'image/png' },
{ url: '/learn/favicon-512x512.png', sizes: '512x512', type: 'image/png' },
],
apple: [{ url: '/learn/apple-touch-icon.png' }],
},
Expand Down Expand Up @@ -52,6 +56,8 @@ export default function RootLayout({ children }: Readonly<{ children: React.Reac
return (
<html lang="en" className={inter.variable}>
<body className="min-h-screen font-sans">
<PwaMetaTags />
<ServiceWorkerRegistrar />
<LaunchGate>{children}</LaunchGate>
{process.env.NODE_ENV === 'production' && (
<>
Expand Down
27 changes: 27 additions & 0 deletions components/PwaMetaTags.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use client'

import { useEffect } from 'react'

/**
* Injects iOS PWA meta tags. Next.js Metadata API does not output
* apple-mobile-web-app-capable in a way that enables Safari splash screens,
* so we inject these on the client.
*/
export function PwaMetaTags() {
useEffect(() => {
const tags: [string, Record<string, string>][] = [
['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }],
['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'default' }],
['meta', { name: 'apple-mobile-web-app-title', content: 'Learn' }],
]
const elements: HTMLElement[] = []
tags.forEach(([tagName, attrs]) => {
const el = document.createElement(tagName)
Object.entries(attrs).forEach(([k, v]) => el.setAttribute(k, v))
document.head.appendChild(el)
elements.push(el)
})
return () => elements.forEach((el) => el.remove())
}, [])
return null
}
11 changes: 11 additions & 0 deletions components/ServiceWorkerRegistrar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
'use client'

import { useEffect } from 'react'

export function ServiceWorkerRegistrar() {
useEffect(() => {
if (typeof window === 'undefined' || !('serviceWorker' in navigator)) return
navigator.serviceWorker.register('/sw.js').catch(() => {})
}, [])
return null
}
Loading
Loading