In this guide we are going to setup a PWA using Dynamic and Vite, React & Typescript.
Full code example
You can find the full code from this example here.
Pre-requisites
- Node installed
- Boilerplate project created with Vite
npm create vite@latest dynamic-pwa -- --template react-ts
Dynamic Setup
With a basic project in place, we can now setup the Dynamic React SDK
Install Dynamic Packages
npm install @dynamic-labs/sdk-react-core @dynamic-labs/ethereum
Add the DynamicContextProvider
In the src/main.tsx
file we can add the DynamicContextProvider with an environment ID
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";
import "./index.css";
import { DynamicContextProvider } from "@dynamic-labs/sdk-react-core";
import { EthereumWalletConnectors } from "@dynamic-labs/ethereum";
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<DynamicContextProvider
settings={{
environmentId: "96bae37d-7ed7-44aa-9081-79bb984508fe",
walletConnectors: [EthereumWalletConnectors],
}}
>
<App />
</DynamicContextProvider>
</React.StrictMode>
);
Over in the App file, we are going to use the DynamicWidget for users to be able to authenticate using the Dynamic UI
Now, in the src/App.tsx
file, we can add the DynamicWidget component
import { DynamicWidget } from "@dynamic-labs/sdk-react-core";
function App() {
return (
<DynamicWidget />
);
}
export default App;
Great, now Dynamic is fully added and we can get start with the PWA setup!
PWA Setup
Install Dependencies
npm install -D vite-plugin-pwa
Setup PWA
For this app to became a PWA we will need to generate a manifest file with some extra icons that the OS will use.
First, we can update our vite.config.ts
file with vite-plugin-pwa:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { VitePWA } from "vite-plugin-pwa";
export default defineConfig({
publicDir: "public",
plugins: [
react(),
VitePWA({
registerType: "autoUpdate",
devOptions: {
enabled: true,
},
includeAssets: [
"logo.png",
"apple-touch-icon.png",
"mask-icon.svg",
"icon.svg",
],
manifest: {
name: "My Awesome DApp",
short_name: "Dynamic PWA",
description: "My Awesome DApp description",
theme_color: "#ffffff",
icons: [
{
src: "logo.png",
sizes: "192x192",
type: "image/png",
},
{
purpose: "any maskable",
sizes: "260x260",
src: "/apple-touch-icon.png",
type: "image/png",
},
],
},
}),
],
});
We also need to add some images like logo.png
and apple-touch-icon.png
to our public
to serve as the PWA icons.
Now we have to specify in the index.html
file some basic information about the PWA:
So, add the following to the head
tag
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Dynamic PWA</title>
<meta name="description" content="My Awesome DApp description" />
<link rel="icon" href="/logo.png" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180" />
<link rel="mask-icon" href="/logo.png" color="#FFFFFF" />
<meta name="theme-color" content="#ffffff" />
<link rel="manifest" href="/manifest.webmanifest" />
</head>
Let’s add an install button so users can install our PWA.
We can add a hook to src/useInstallPWA.ts
that allows us to trigger the PWA installation:
import { useCallback } from "react";
let deferredPrompt: Event | null = null;
const handleBeforeInstallPrompt = (event: Event) => {
event.preventDefault();
deferredPrompt = event;
};
window.addEventListener("beforeinstallprompt", handleBeforeInstallPrompt);
export const useInstallPWA = () =>
useCallback(() => {
if (deferredPrompt) {
(deferredPrompt as any).prompt();
(deferredPrompt as any).userChoice.then(() => {
deferredPrompt = null;
});
}
}, []);
Then we can use useInstallPWA in the src/main.tsx
file to prompt the user to install the PWA:
import { DynamicWidget } from "@dynamic-labs/sdk-react-core";
import { useInstallPWA } from "./useInstallPWA";
function App() {
const installPWA = useInstallPWA();
return (
<>
<DynamicWidget />
<button onClick={installPWA}>Install PWA</button>
</>
);
}
export default App;
Perfect, now you can serve your DApp under https
and install the PWA on your computer or phone, then authenticate with Dynamic!