PWA & Mobile Experience
Progressive Web App configuration and mobile-first responsive design patterns
PWA & Mobile Experience
SavvySolve is built as a Progressive Web App (PWA) with mobile-first design principles. This means users can install the app on their home screen and use it like a native application, which is particularly important for our target audience of seniors who may be more comfortable with app-like experiences than browser tabs.
Progressive Web App
The PWA configuration enables users to "Add to Home Screen" on both iOS and Android devices. Once installed, SavvySolve launches in standalone mode without browser chrome, providing a native app experience.
Web App Manifest
The manifest file defines how the app appears when installed on a user's device.
{
"name": "SavvySolve - On-Demand Tech Support",
"short_name": "SavvySolve",
"description": "The DoorDash of getting things done digitally.",
"start_url": "/",
"display": "standalone",
"background_color": "#FFFFFF",
"theme_color": "#1B0F40",
"orientation": "portrait-primary",
"icons": [
{
"src": "/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any"
},
{
"src": "/icons/icon-maskable-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}Key configuration choices:
display: standaloneremoves the browser UI, making the app feel nativetheme_color: #1B0F40(SavvySolve purple) colors the status bar on Androidorientation: portrait-primaryoptimizes for phone usage patterns- Maskable icons ensure proper display on Android devices with adaptive icon shapes
Next.js Metadata Integration
The manifest and PWA metadata are configured in the root layout using Next.js 13+ metadata API.
export const metadata: Metadata = {
title: "SavvySolve",
description: "The DoorDash of getting things done digitally.",
manifest: "/manifest.json",
themeColor: "#1B0F40",
appleWebApp: {
capable: true,
statusBarStyle: "default",
title: "SavvySolve",
},
icons: {
icon: [
{ url: "/icons/favicon-16x16.png", sizes: "16x16", type: "image/png" },
{ url: "/icons/favicon-32x32.png", sizes: "32x32", type: "image/png" },
],
apple: [
{ url: "/icons/apple-touch-icon.png", sizes: "180x180", type: "image/png" },
],
},
};App Shortcuts
The manifest includes shortcuts that appear when users long-press the app icon.
{
"shortcuts": [
{
"name": "Get Help",
"short_name": "Help",
"description": "Submit a new support request",
"url": "/?action=new"
},
{
"name": "Dashboard",
"short_name": "Dashboard",
"description": "View your dashboard",
"url": "/dashboard"
}
]
}Icon Generation
PWA icons are generated from a single SVG source using a build script.
import sharp from "sharp";
const ICON_SIZES = [72, 96, 128, 144, 152, 192, 384, 512];
async function generateIcons() {
for (const size of ICON_SIZES) {
await sharp("public/icons/icon.svg")
.resize(size, size)
.png()
.toFile(`public/icons/icon-${size}x${size}.png`);
}
}Run bun run scripts/generate-pwa-icons.ts after modifying the source SVG.
Mobile-First Touch Targets
Following WCAG AAA guidelines for touch accessibility, all interactive elements have a minimum touch target of 44x44 pixels on mobile devices. This is especially important for our senior user demographic.
Responsive Component Sizing
UI components use mobile-first sizing that reduces on larger screens.
const buttonVariants = cva(
"... touch-manipulation",
{
variants: {
size: {
// Mobile-first: 44px minimum, smaller on desktop
default: "min-h-11 px-4 py-2 md:min-h-9",
sm: "min-h-11 px-3 md:min-h-8",
icon: "min-h-11 min-w-11 md:size-9",
},
},
}
);The touch-manipulation CSS class eliminates the 300ms tap delay on mobile browsers.
Input Components
Form inputs follow the same pattern with comfortable touch targets on mobile.
<input
className={cn(
// Mobile: 44px height, comfortable padding
"min-h-11 px-3 py-2 text-base",
// Desktop: smaller, tighter
"md:min-h-9 md:py-1 md:text-sm",
"touch-manipulation",
)}
/>Using text-base (16px) on mobile prevents iOS from zooming in when focusing inputs.
Responsive Layout System
The dashboard uses a responsive breakpoint strategy optimized for tablets and phones.
Breakpoint Strategy
| Breakpoint | Width | Usage |
|---|---|---|
| Default | 0-639px | Mobile phones - single column, bottom nav |
sm | 640px+ | Large phones - 2 columns where appropriate |
md | 768px+ | Small tablets - still use bottom nav |
lg | 1024px+ | Tablets/desktop - sidebar navigation |
Navigation Switching
The sidebar appears only on large screens (1024px+), while mobile and tablet users see the bottom navigation bar.
<div className="flex h-screen">
{/* Sidebar: hidden until lg breakpoint */}
<Sidebar className="hidden lg:flex" />
<div className="flex flex-1 flex-col">
<main className="flex-1 p-4 pb-20 lg:p-6 lg:pb-6">
{children}
</main>
</div>
{/* Bottom nav: visible until lg breakpoint */}
<BottomNav className="lg:hidden" />
</div>The extra bottom padding (pb-20) on mobile accounts for the fixed bottom navigation bar.
Session Interface Grid
Complex layouts like the session interface adapt to screen size.
<div className="grid gap-4 sm:gap-6 md:grid-cols-2 lg:grid-cols-3">
{/* Timer */}
<div>
<SessionTimer />
</div>
{/* Chat - responsive height */}
<div>
<ChatWindow className="h-[400px] sm:h-[450px] lg:h-[500px]" />
</div>
{/* Notes - spans 2 cols on tablet */}
<div className="md:col-span-2 lg:col-span-1">
<SessionNotes />
</div>
</div>This creates:
- Mobile: Single column, stacked vertically
- Tablet (md): 2 columns with notes spanning full width below
- Desktop (lg): 3 equal columns side by side
Testing the PWA
Chrome DevTools
- Open DevTools → Application → Manifest
- Verify all icons load correctly
- Check "Installable" status in Lighthouse audit
Installing on Devices
iOS Safari:
- Navigate to the app
- Tap Share button
- Select "Add to Home Screen"
Android Chrome:
- Navigate to the app
- Tap menu (three dots)
- Select "Install app" or "Add to Home Screen"
Lighthouse Audit
Run a Lighthouse PWA audit to verify:
- Manifest is valid and complete
- Icons are correct sizes
- Theme color is set
- App is installable
The app should pass all PWA installability checks.
Future Enhancements
The current PWA implementation enables installation but does not include offline support. Future improvements could include:
- Service Worker: Cache static assets for offline access
- Background Sync: Queue messages when offline
- Push Notifications: Alert users to new messages or session updates
These would require additional configuration with Next.js and a service worker registration strategy.