@undp/create-app 0.91.0 → 0.91.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -3
- package/bin/generateFiles/generateIndexHtml.js +13 -5
- package/bin/generateFiles/generatePackageJson.js +1 -0
- package/bin/generateFiles/generateStaticWebAppConfig.js +15 -5
- package/bin/generateFiles/generateViteConfig.js +6 -0
- package/bin/promptUser.js +146 -127
- package/bin/templates/next/auth/README.md +17 -0
- package/bin/templates/next/basic/README.md +17 -0
- package/bin/templates/vite/basic/.github/ISSUE_TEMPLATE/launch-checklist.md +73 -0
- package/bin/templates/vite/basic/README.md +40 -5
- package/bin/templates/vite/query/.github/ISSUE_TEMPLATE/launch-checklist.md +73 -0
- package/bin/templates/vite/query/README.md +39 -5
- package/bin/templates/vite/query+router/.github/ISSUE_TEMPLATE/launch-checklist.md +73 -0
- package/bin/templates/vite/query+router/README.md +17 -0
- package/bin/templates/vite/router/.github/ISSUE_TEMPLATE/launch-checklist.md +73 -0
- package/bin/templates/vite/router/README.md +17 -0
- package/bin/templates/viteWithLanguage/basic/.github/ISSUE_TEMPLATE/launch-checklist.md +73 -0
- package/bin/templates/viteWithLanguage/basic/README.md +52 -5
- package/bin/templates/viteWithLanguage/query/.github/ISSUE_TEMPLATE/launch-checklist.md +73 -0
- package/bin/templates/viteWithLanguage/query/README.md +53 -5
- package/bin/templates/viteWithLanguage/query+router/.github/ISSUE_TEMPLATE/launch-checklist.md +72 -0
- package/bin/templates/viteWithLanguage/query+router/README.md +17 -0
- package/bin/templates/viteWithLanguage/router/.github/ISSUE_TEMPLATE/launch-checklist.md +73 -0
- package/bin/templates/viteWithLanguage/router/README.md +17 -0
- package/package.json +1 -1
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Launch checklist
|
|
3
|
+
about: Pre-launch checks to complete before going to production
|
|
4
|
+
title: "Launch checklist"
|
|
5
|
+
labels: launch
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<!-- Tick items as you go. Don't close this issue until every box is checked or explicitly marked N/A with a reason. -->
|
|
10
|
+
|
|
11
|
+
## Metadata & SEO
|
|
12
|
+
|
|
13
|
+
- [ ] Favicon added (`favicon.ico` + SVG).
|
|
14
|
+
- [ ] `<meta name="theme-color">` added.
|
|
15
|
+
- [ ] `<html lang="…">` is set correctly.
|
|
16
|
+
- [ ] Every route has a unique `<title>` and `<meta name="description">`.
|
|
17
|
+
- [ ] Every route has a canonical URL: `<link rel="canonical" href="…">`.
|
|
18
|
+
- [ ] Open Graph and Twitter tags are added (globally in `index.html` or per route). Use absolute URLs for `og:url` and `og:image`:
|
|
19
|
+
|
|
20
|
+
```html
|
|
21
|
+
<meta property="og:type" content="website" />
|
|
22
|
+
<meta property="og:site_name" content="SITE_NAME" />
|
|
23
|
+
<meta property="og:title" content="TITLE" />
|
|
24
|
+
<meta property="og:description" content="DESCRIPTION" />
|
|
25
|
+
<meta property="og:url" content="https://example.com/page" />
|
|
26
|
+
<meta property="og:image" content="https://example.com/og-image.png" />
|
|
27
|
+
<meta property="og:image:width" content="1200" />
|
|
28
|
+
<meta property="og:image:height" content="630" />
|
|
29
|
+
<meta property="og:image:alt" content="IMAGE_ALT_TEXT" />
|
|
30
|
+
<meta name="twitter:card" content="summary_large_image" />
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
- [ ] Social previews verified with a preview tool (e.g. opengraph.xyz, LinkedIn Post Inspector).
|
|
34
|
+
- [ ] `robots.txt` and `sitemap.xml` are in place.
|
|
35
|
+
- [ ] `<meta name="robots" content="noindex">` is added to routes that should not be indexed for search.
|
|
36
|
+
- [ ] Production is indexable (no leftover `noindex`), and staging is **not** indexable.
|
|
37
|
+
- [ ] `apple-touch-icon` (180×180) added - only needed for site which the users might "install".
|
|
38
|
+
- [ ] `site.webmanifest` added - only needed for site which the users might "install".
|
|
39
|
+
|
|
40
|
+
## Functionality & QA
|
|
41
|
+
|
|
42
|
+
- [ ] All routes load, including on direct visit or refresh (host has SPA fallback routing).
|
|
43
|
+
- [ ] A custom 404 page exists, and React error boundaries catch runtime errors.
|
|
44
|
+
- [ ] No errors or warnings in the browser console.
|
|
45
|
+
- [ ] All forms, links and external integrations work in production.
|
|
46
|
+
- [ ] Design QA is complete and signed off.
|
|
47
|
+
- [ ] The layout works on all viewport widths from 360px up. At minimum, check 360, 768, 1024 and 1440px.
|
|
48
|
+
- [ ] Tested in the latest Chrome, Firefox, Edge and Safari.
|
|
49
|
+
|
|
50
|
+
## Performance
|
|
51
|
+
|
|
52
|
+
- [ ] Initial JS on first page load is ≤ 175 KB gzipped.
|
|
53
|
+
- [ ] Main CSS file is ≤ 50 KB gzipped.
|
|
54
|
+
- [ ] Images are optimised (WebP/AVIF, correctly sized, ≤ 75 KB each, lazy-loaded below the fold).
|
|
55
|
+
- [ ] Fonts are subset and preloaded, with `font-display: swap`.
|
|
56
|
+
- [ ] Lighthouse scores (run in incognito against production):
|
|
57
|
+
|
|
58
|
+
| Category | Desktop | Mobile |
|
|
59
|
+
|----------------|---------|--------|
|
|
60
|
+
| Performance | ≥ 90 | ≥ 70 |
|
|
61
|
+
| Accessibility | ≥ 90 | ≥ 90 |
|
|
62
|
+
| Best Practices | ≥ 90 | ≥ 90 |
|
|
63
|
+
| SEO | ≥ 90 | ≥ 90 |
|
|
64
|
+
|
|
65
|
+
## Security & infrastructure
|
|
66
|
+
|
|
67
|
+
- [ ] `npm audit` shows no high or critical vulnerabilities.
|
|
68
|
+
- [ ] `npm audit --omit=dev` shows no vulnerabilities.
|
|
69
|
+
- [ ] No secrets or private API keys in the client bundle.
|
|
70
|
+
|
|
71
|
+
## Analytics & privacy
|
|
72
|
+
|
|
73
|
+
- [ ] Google Analytics and/or Microsoft Clarity are installed and events are confirmed arriving from production.
|
|
@@ -59,7 +59,9 @@ Data fetching is powered by [TanStack Query](https://tanstack.com/query) for eff
|
|
|
59
59
|
|
|
60
60
|
To embed the visualization on an external page, include:
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
### Option 1: Iframe
|
|
63
|
+
|
|
64
|
+
__HTML Placeholder__
|
|
63
65
|
|
|
64
66
|
```html
|
|
65
67
|
<iframe
|
|
@@ -70,16 +72,15 @@ To embed the visualization on an external page, include:
|
|
|
70
72
|
/>
|
|
71
73
|
```
|
|
72
74
|
|
|
73
|
-
|
|
75
|
+
__Required `<script>`__
|
|
74
76
|
|
|
75
|
-
```
|
|
77
|
+
```js
|
|
76
78
|
<script>
|
|
77
79
|
var iframe = document.getElementById('my-embed');
|
|
78
80
|
window.addEventListener('message', function (e) {
|
|
79
|
-
if (e.origin !== '
|
|
81
|
+
if (e.origin !== 'APP_URL') return;
|
|
80
82
|
if (e.source !== iframe.contentWindow) return;
|
|
81
83
|
if (e.data && e.data.type === 'iframe-height') {
|
|
82
|
-
console.log('new height', e.data.height);
|
|
83
84
|
iframe.style.height = e.data.height + 'px';
|
|
84
85
|
}
|
|
85
86
|
});
|
|
@@ -88,6 +89,39 @@ To embed the visualization on an external page, include:
|
|
|
88
89
|
|
|
89
90
|
_This script listens for height messages from the embedded web app and resizes the iframe to match its content, so the app displays without an inner scrollbar._
|
|
90
91
|
|
|
92
|
+
### Option 2: Embed in the page (Worst performance better UX)
|
|
93
|
+
|
|
94
|
+
__HTML Placeholder__
|
|
95
|
+
|
|
96
|
+
```html
|
|
97
|
+
<div id="root"></div>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
__Required `<script>` and `<link>` tags__
|
|
101
|
+
|
|
102
|
+
```html
|
|
103
|
+
<link rel="dns-prefetch" href="{{Visualization URL}}">
|
|
104
|
+
<script defer="defer" type="module" src="{{Visualization URL}}/index.js"></script>
|
|
105
|
+
<link rel="stylesheet" href="{{Visualization URL}}/style.css"></link>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## ✅ Launch Checklist
|
|
109
|
+
|
|
110
|
+
Before deploying to production, complete the launch checklist. It covers metadata and SEO, analytics, QA, accessibility, performance, security headers and caching.
|
|
111
|
+
|
|
112
|
+
The checklist is set up as a GitHub issue template, so each launch gets its own tickable copy:
|
|
113
|
+
|
|
114
|
+
1. Go to **Issues → New issue** in this repository.
|
|
115
|
+
2. Select **Launch checklist**.
|
|
116
|
+
3. Assign yourself, and click **Create**.
|
|
117
|
+
4. Tick items off as you complete them. The issue list shows progress (e.g. "7 of 32 tasks").
|
|
118
|
+
|
|
119
|
+
Or open it directly: [Create launch checklist issue](../../issues/new?template=launch-checklist.md)
|
|
120
|
+
|
|
121
|
+
Don't close the issue until every item is checked, or marked N/A with a reason.
|
|
122
|
+
|
|
123
|
+
The template lives in `.github/ISSUE_TEMPLATE/launch-checklist.md`.
|
|
124
|
+
|
|
91
125
|
## 📬 Contact us
|
|
92
126
|
|
|
93
127
|
For questions or feedback, contact us at [data@undp.org](mailto:data@undp.org).
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Launch checklist
|
|
3
|
+
about: Pre-launch checks to complete before going to production
|
|
4
|
+
title: "Launch checklist"
|
|
5
|
+
labels: launch
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<!-- Tick items as you go. Don't close this issue until every box is checked or explicitly marked N/A with a reason. -->
|
|
10
|
+
|
|
11
|
+
## Metadata & SEO
|
|
12
|
+
|
|
13
|
+
- [ ] Favicon added (`favicon.ico` + SVG).
|
|
14
|
+
- [ ] `<meta name="theme-color">` added.
|
|
15
|
+
- [ ] `<html lang="…">` is set correctly.
|
|
16
|
+
- [ ] Every route has a unique `<title>` and `<meta name="description">`.
|
|
17
|
+
- [ ] Every route has a canonical URL: `<link rel="canonical" href="…">`.
|
|
18
|
+
- [ ] Open Graph and Twitter tags are added (globally in `index.html` or per route). Use absolute URLs for `og:url` and `og:image`:
|
|
19
|
+
|
|
20
|
+
```html
|
|
21
|
+
<meta property="og:type" content="website" />
|
|
22
|
+
<meta property="og:site_name" content="SITE_NAME" />
|
|
23
|
+
<meta property="og:title" content="TITLE" />
|
|
24
|
+
<meta property="og:description" content="DESCRIPTION" />
|
|
25
|
+
<meta property="og:url" content="https://example.com/page" />
|
|
26
|
+
<meta property="og:image" content="https://example.com/og-image.png" />
|
|
27
|
+
<meta property="og:image:width" content="1200" />
|
|
28
|
+
<meta property="og:image:height" content="630" />
|
|
29
|
+
<meta property="og:image:alt" content="IMAGE_ALT_TEXT" />
|
|
30
|
+
<meta name="twitter:card" content="summary_large_image" />
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
- [ ] Social previews verified with a preview tool (e.g. opengraph.xyz, LinkedIn Post Inspector).
|
|
34
|
+
- [ ] `robots.txt` and `sitemap.xml` are in place.
|
|
35
|
+
- [ ] `<meta name="robots" content="noindex">` is added to routes that should not be indexed for search.
|
|
36
|
+
- [ ] Production is indexable (no leftover `noindex`), and staging is **not** indexable.
|
|
37
|
+
- [ ] `apple-touch-icon` (180×180) added - only needed for site which the users might "install".
|
|
38
|
+
- [ ] `site.webmanifest` added - only needed for site which the users might "install".
|
|
39
|
+
|
|
40
|
+
## Functionality & QA
|
|
41
|
+
|
|
42
|
+
- [ ] All routes load, including on direct visit or refresh (host has SPA fallback routing).
|
|
43
|
+
- [ ] A custom 404 page exists, and React error boundaries catch runtime errors.
|
|
44
|
+
- [ ] No errors or warnings in the browser console.
|
|
45
|
+
- [ ] All forms, links and external integrations work in production.
|
|
46
|
+
- [ ] Design QA is complete and signed off.
|
|
47
|
+
- [ ] The layout works on all viewport widths from 360px up. At minimum, check 360, 768, 1024 and 1440px.
|
|
48
|
+
- [ ] Tested in the latest Chrome, Firefox, Edge and Safari.
|
|
49
|
+
|
|
50
|
+
## Performance
|
|
51
|
+
|
|
52
|
+
- [ ] Initial JS on first page load is ≤ 175 KB gzipped.
|
|
53
|
+
- [ ] Main CSS file is ≤ 50 KB gzipped.
|
|
54
|
+
- [ ] Images are optimised (WebP/AVIF, correctly sized, ≤ 75 KB each, lazy-loaded below the fold).
|
|
55
|
+
- [ ] Fonts are subset and preloaded, with `font-display: swap`.
|
|
56
|
+
- [ ] Lighthouse scores (run in incognito against production):
|
|
57
|
+
|
|
58
|
+
| Category | Desktop | Mobile |
|
|
59
|
+
|----------------|---------|--------|
|
|
60
|
+
| Performance | ≥ 90 | ≥ 70 |
|
|
61
|
+
| Accessibility | ≥ 90 | ≥ 90 |
|
|
62
|
+
| Best Practices | ≥ 90 | ≥ 90 |
|
|
63
|
+
| SEO | ≥ 90 | ≥ 90 |
|
|
64
|
+
|
|
65
|
+
## Security & infrastructure
|
|
66
|
+
|
|
67
|
+
- [ ] `npm audit` shows no high or critical vulnerabilities.
|
|
68
|
+
- [ ] `npm audit --omit=dev` shows no vulnerabilities.
|
|
69
|
+
- [ ] No secrets or private API keys in the client bundle.
|
|
70
|
+
|
|
71
|
+
## Analytics & privacy
|
|
72
|
+
|
|
73
|
+
- [ ] Google Analytics and/or Microsoft Clarity are installed and events are confirmed arriving from production.
|
|
@@ -106,6 +106,23 @@ More info: [Link documentation](https://tanstack.com/router/v1/docs/framework/re
|
|
|
106
106
|
|
|
107
107
|
Data fetching is powered by [TanStack Query](https://tanstack.com/query) for efficient, declarative data fetching and caching.
|
|
108
108
|
|
|
109
|
+
## ✅ Launch Checklist
|
|
110
|
+
|
|
111
|
+
Before deploying to production, complete the launch checklist. It covers metadata and SEO, analytics, QA, accessibility, performance, security headers and caching.
|
|
112
|
+
|
|
113
|
+
The checklist is set up as a GitHub issue template, so each launch gets its own tickable copy:
|
|
114
|
+
|
|
115
|
+
1. Go to **Issues → New issue** in this repository.
|
|
116
|
+
2. Select **Launch checklist**.
|
|
117
|
+
3. Assign yourself, and click **Create**.
|
|
118
|
+
4. Tick items off as you complete them. The issue list shows progress (e.g. "7 of 32 tasks").
|
|
119
|
+
|
|
120
|
+
Or open it directly: [Create launch checklist issue](../../issues/new?template=launch-checklist.md)
|
|
121
|
+
|
|
122
|
+
Don't close the issue until every item is checked, or marked N/A with a reason.
|
|
123
|
+
|
|
124
|
+
The template lives in `.github/ISSUE_TEMPLATE/launch-checklist.md`.
|
|
125
|
+
|
|
109
126
|
## 📬 Contact us
|
|
110
127
|
|
|
111
128
|
For questions or feedback, contact us at [data@undp.org](mailto:data@undp.org).
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Launch checklist
|
|
3
|
+
about: Pre-launch checks to complete before going to production
|
|
4
|
+
title: "Launch checklist"
|
|
5
|
+
labels: launch
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<!-- Tick items as you go. Don't close this issue until every box is checked or explicitly marked N/A with a reason. -->
|
|
10
|
+
|
|
11
|
+
## Metadata & SEO
|
|
12
|
+
|
|
13
|
+
- [ ] Favicon added (`favicon.ico` + SVG).
|
|
14
|
+
- [ ] `<meta name="theme-color">` added.
|
|
15
|
+
- [ ] `<html lang="…">` is set correctly.
|
|
16
|
+
- [ ] Every route has a unique `<title>` and `<meta name="description">`.
|
|
17
|
+
- [ ] Every route has a canonical URL: `<link rel="canonical" href="…">`.
|
|
18
|
+
- [ ] Open Graph and Twitter tags are added (globally in `index.html` or per route). Use absolute URLs for `og:url` and `og:image`:
|
|
19
|
+
|
|
20
|
+
```html
|
|
21
|
+
<meta property="og:type" content="website" />
|
|
22
|
+
<meta property="og:site_name" content="SITE_NAME" />
|
|
23
|
+
<meta property="og:title" content="TITLE" />
|
|
24
|
+
<meta property="og:description" content="DESCRIPTION" />
|
|
25
|
+
<meta property="og:url" content="https://example.com/page" />
|
|
26
|
+
<meta property="og:image" content="https://example.com/og-image.png" />
|
|
27
|
+
<meta property="og:image:width" content="1200" />
|
|
28
|
+
<meta property="og:image:height" content="630" />
|
|
29
|
+
<meta property="og:image:alt" content="IMAGE_ALT_TEXT" />
|
|
30
|
+
<meta name="twitter:card" content="summary_large_image" />
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
- [ ] Social previews verified with a preview tool (e.g. opengraph.xyz, LinkedIn Post Inspector).
|
|
34
|
+
- [ ] `robots.txt` and `sitemap.xml` are in place.
|
|
35
|
+
- [ ] `<meta name="robots" content="noindex">` is added to routes that should not be indexed for search.
|
|
36
|
+
- [ ] Production is indexable (no leftover `noindex`), and staging is **not** indexable.
|
|
37
|
+
- [ ] `apple-touch-icon` (180×180) added - only needed for site which the users might "install".
|
|
38
|
+
- [ ] `site.webmanifest` added - only needed for site which the users might "install".
|
|
39
|
+
|
|
40
|
+
## Functionality & QA
|
|
41
|
+
|
|
42
|
+
- [ ] All routes load, including on direct visit or refresh (host has SPA fallback routing).
|
|
43
|
+
- [ ] A custom 404 page exists, and React error boundaries catch runtime errors.
|
|
44
|
+
- [ ] No errors or warnings in the browser console.
|
|
45
|
+
- [ ] All forms, links and external integrations work in production.
|
|
46
|
+
- [ ] Design QA is complete and signed off.
|
|
47
|
+
- [ ] The layout works on all viewport widths from 360px up. At minimum, check 360, 768, 1024 and 1440px.
|
|
48
|
+
- [ ] Tested in the latest Chrome, Firefox, Edge and Safari.
|
|
49
|
+
|
|
50
|
+
## Performance
|
|
51
|
+
|
|
52
|
+
- [ ] Initial JS on first page load is ≤ 175 KB gzipped.
|
|
53
|
+
- [ ] Main CSS file is ≤ 50 KB gzipped.
|
|
54
|
+
- [ ] Images are optimised (WebP/AVIF, correctly sized, ≤ 75 KB each, lazy-loaded below the fold).
|
|
55
|
+
- [ ] Fonts are subset and preloaded, with `font-display: swap`.
|
|
56
|
+
- [ ] Lighthouse scores (run in incognito against production):
|
|
57
|
+
|
|
58
|
+
| Category | Desktop | Mobile |
|
|
59
|
+
|----------------|---------|--------|
|
|
60
|
+
| Performance | ≥ 90 | ≥ 70 |
|
|
61
|
+
| Accessibility | ≥ 90 | ≥ 90 |
|
|
62
|
+
| Best Practices | ≥ 90 | ≥ 90 |
|
|
63
|
+
| SEO | ≥ 90 | ≥ 90 |
|
|
64
|
+
|
|
65
|
+
## Security & infrastructure
|
|
66
|
+
|
|
67
|
+
- [ ] `npm audit` shows no high or critical vulnerabilities.
|
|
68
|
+
- [ ] `npm audit --omit=dev` shows no vulnerabilities.
|
|
69
|
+
- [ ] No secrets or private API keys in the client bundle.
|
|
70
|
+
|
|
71
|
+
## Analytics & privacy
|
|
72
|
+
|
|
73
|
+
- [ ] Google Analytics and/or Microsoft Clarity are installed and events are confirmed arriving from production.
|
|
@@ -101,6 +101,23 @@ import { Link } from "@tanstack/react-router";
|
|
|
101
101
|
|
|
102
102
|
More info: [Link documentation](https://tanstack.com/router/v1/docs/framework/react/api/router/linkComponent).
|
|
103
103
|
|
|
104
|
+
## ✅ Launch Checklist
|
|
105
|
+
|
|
106
|
+
Before deploying to production, complete the launch checklist. It covers metadata and SEO, analytics, QA, accessibility, performance, security headers and caching.
|
|
107
|
+
|
|
108
|
+
The checklist is set up as a GitHub issue template, so each launch gets its own tickable copy:
|
|
109
|
+
|
|
110
|
+
1. Go to **Issues → New issue** in this repository.
|
|
111
|
+
2. Select **Launch checklist**.
|
|
112
|
+
3. Assign yourself, and click **Create**.
|
|
113
|
+
4. Tick items off as you complete them. The issue list shows progress (e.g. "7 of 32 tasks").
|
|
114
|
+
|
|
115
|
+
Or open it directly: [Create launch checklist issue](../../issues/new?template=launch-checklist.md)
|
|
116
|
+
|
|
117
|
+
Don't close the issue until every item is checked, or marked N/A with a reason.
|
|
118
|
+
|
|
119
|
+
The template lives in `.github/ISSUE_TEMPLATE/launch-checklist.md`.
|
|
120
|
+
|
|
104
121
|
## 📬 Contact us
|
|
105
122
|
|
|
106
123
|
For questions or feedback, contact us at [data@undp.org](mailto:data@undp.org).
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Launch checklist
|
|
3
|
+
about: Pre-launch checks to complete before going to production
|
|
4
|
+
title: "Launch checklist"
|
|
5
|
+
labels: launch
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<!-- Tick items as you go. Don't close this issue until every box is checked or explicitly marked N/A with a reason. -->
|
|
10
|
+
|
|
11
|
+
## Metadata & SEO
|
|
12
|
+
|
|
13
|
+
- [ ] Favicon added (`favicon.ico` + SVG).
|
|
14
|
+
- [ ] `<meta name="theme-color">` added.
|
|
15
|
+
- [ ] `<html lang="…">` is set correctly.
|
|
16
|
+
- [ ] Every route has a unique `<title>` and `<meta name="description">`.
|
|
17
|
+
- [ ] Every route has a canonical URL: `<link rel="canonical" href="…">`.
|
|
18
|
+
- [ ] Open Graph and Twitter tags are added (globally in `index.html` or per route). Use absolute URLs for `og:url` and `og:image`:
|
|
19
|
+
|
|
20
|
+
```html
|
|
21
|
+
<meta property="og:type" content="website" />
|
|
22
|
+
<meta property="og:site_name" content="SITE_NAME" />
|
|
23
|
+
<meta property="og:title" content="TITLE" />
|
|
24
|
+
<meta property="og:description" content="DESCRIPTION" />
|
|
25
|
+
<meta property="og:url" content="https://example.com/page" />
|
|
26
|
+
<meta property="og:image" content="https://example.com/og-image.png" />
|
|
27
|
+
<meta property="og:image:width" content="1200" />
|
|
28
|
+
<meta property="og:image:height" content="630" />
|
|
29
|
+
<meta property="og:image:alt" content="IMAGE_ALT_TEXT" />
|
|
30
|
+
<meta name="twitter:card" content="summary_large_image" />
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
- [ ] Social previews verified with a preview tool (e.g. opengraph.xyz, LinkedIn Post Inspector).
|
|
34
|
+
- [ ] `robots.txt` and `sitemap.xml` are in place.
|
|
35
|
+
- [ ] `<meta name="robots" content="noindex">` is added to routes that should not be indexed for search.
|
|
36
|
+
- [ ] Production is indexable (no leftover `noindex`), and staging is **not** indexable.
|
|
37
|
+
- [ ] `apple-touch-icon` (180×180) added - only needed for site which the users might "install".
|
|
38
|
+
- [ ] `site.webmanifest` added - only needed for site which the users might "install".
|
|
39
|
+
|
|
40
|
+
## Functionality & QA
|
|
41
|
+
|
|
42
|
+
- [ ] All routes load, including on direct visit or refresh (host has SPA fallback routing).
|
|
43
|
+
- [ ] A custom 404 page exists, and React error boundaries catch runtime errors.
|
|
44
|
+
- [ ] No errors or warnings in the browser console.
|
|
45
|
+
- [ ] All forms, links and external integrations work in production.
|
|
46
|
+
- [ ] Design QA is complete and signed off.
|
|
47
|
+
- [ ] The layout works on all viewport widths from 360px up. At minimum, check 360, 768, 1024 and 1440px.
|
|
48
|
+
- [ ] Tested in the latest Chrome, Firefox, Edge and Safari.
|
|
49
|
+
|
|
50
|
+
## Performance
|
|
51
|
+
|
|
52
|
+
- [ ] Initial JS on first page load is ≤ 175 KB gzipped.
|
|
53
|
+
- [ ] Main CSS file is ≤ 50 KB gzipped.
|
|
54
|
+
- [ ] Images are optimised (WebP/AVIF, correctly sized, ≤ 75 KB each, lazy-loaded below the fold).
|
|
55
|
+
- [ ] Fonts are subset and preloaded, with `font-display: swap`.
|
|
56
|
+
- [ ] Lighthouse scores (run in incognito against production):
|
|
57
|
+
|
|
58
|
+
| Category | Desktop | Mobile |
|
|
59
|
+
|----------------|---------|--------|
|
|
60
|
+
| Performance | ≥ 90 | ≥ 70 |
|
|
61
|
+
| Accessibility | ≥ 90 | ≥ 90 |
|
|
62
|
+
| Best Practices | ≥ 90 | ≥ 90 |
|
|
63
|
+
| SEO | ≥ 90 | ≥ 90 |
|
|
64
|
+
|
|
65
|
+
## Security & infrastructure
|
|
66
|
+
|
|
67
|
+
- [ ] `npm audit` shows no high or critical vulnerabilities.
|
|
68
|
+
- [ ] `npm audit --omit=dev` shows no vulnerabilities.
|
|
69
|
+
- [ ] No secrets or private API keys in the client bundle.
|
|
70
|
+
|
|
71
|
+
## Analytics & privacy
|
|
72
|
+
|
|
73
|
+
- [ ] Google Analytics and/or Microsoft Clarity are installed and events are confirmed arriving from production.
|
|
@@ -66,22 +66,69 @@ This project uses [Tailwind CSS](https://tailwindcss.com/) for styling and and i
|
|
|
66
66
|
|
|
67
67
|
To embed the visualization on an external page, include:
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
### Option 1: Iframe
|
|
70
|
+
|
|
71
|
+
__HTML Placeholder__
|
|
70
72
|
|
|
71
73
|
```html
|
|
72
|
-
<
|
|
74
|
+
<iframe
|
|
75
|
+
id="my-embed"
|
|
76
|
+
src="<url of the app>"
|
|
77
|
+
style="width: 100%; border: 0; display: block;"
|
|
78
|
+
scrolling="no"
|
|
79
|
+
/>
|
|
73
80
|
```
|
|
74
81
|
|
|
75
|
-
|
|
82
|
+
__Required `<script>`__
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
<script>
|
|
86
|
+
var iframe = document.getElementById('my-embed');
|
|
87
|
+
window.addEventListener('message', function (e) {
|
|
88
|
+
if (e.origin !== 'APP_URL') return;
|
|
89
|
+
if (e.source !== iframe.contentWindow) return;
|
|
90
|
+
if (e.data && e.data.type === 'iframe-height') {
|
|
91
|
+
iframe.style.height = e.data.height + 'px';
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
</script>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
_This script listens for height messages from the embedded web app and resizes the iframe to match its content, so the app displays without an inner scrollbar._
|
|
98
|
+
|
|
99
|
+
### Option 2: Embed in the page (Worst performance better UX)
|
|
76
100
|
|
|
101
|
+
__HTML Placeholder__
|
|
102
|
+
|
|
103
|
+
```html
|
|
104
|
+
<div id="root"></div>
|
|
77
105
|
```
|
|
106
|
+
|
|
107
|
+
__Required `<script>` and `<link>` tags__
|
|
108
|
+
|
|
109
|
+
```html
|
|
78
110
|
<link rel="dns-prefetch" href="{{Visualization URL}}">
|
|
79
111
|
<script defer="defer" type="module" src="{{Visualization URL}}/index.js"></script>
|
|
80
|
-
<link rel="modulepreload" crossorigin href="{{Visualization URL}}/react-{{hash}}.js">
|
|
81
|
-
<link rel="modulepreload" crossorigin href="{{Visualization URL}}/undp-{{hash}}.js">
|
|
82
112
|
<link rel="stylesheet" href="{{Visualization URL}}/style.css"></link>
|
|
83
113
|
```
|
|
84
114
|
|
|
115
|
+
## ✅ Launch Checklist
|
|
116
|
+
|
|
117
|
+
Before deploying to production, complete the launch checklist. It covers metadata and SEO, analytics, QA, accessibility, performance, security headers and caching.
|
|
118
|
+
|
|
119
|
+
The checklist is set up as a GitHub issue template, so each launch gets its own tickable copy:
|
|
120
|
+
|
|
121
|
+
1. Go to **Issues → New issue** in this repository.
|
|
122
|
+
2. Select **Launch checklist**.
|
|
123
|
+
3. Assign yourself, and click **Create**.
|
|
124
|
+
4. Tick items off as you complete them. The issue list shows progress (e.g. "7 of 32 tasks").
|
|
125
|
+
|
|
126
|
+
Or open it directly: [Create launch checklist issue](../../issues/new?template=launch-checklist.md)
|
|
127
|
+
|
|
128
|
+
Don't close the issue until every item is checked, or marked N/A with a reason.
|
|
129
|
+
|
|
130
|
+
The template lives in `.github/ISSUE_TEMPLATE/launch-checklist.md`.
|
|
131
|
+
|
|
85
132
|
## 📬 Contact us
|
|
86
133
|
|
|
87
134
|
For questions or feedback, contact us at [data@undp.org](mailto:data@undp.org).
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Launch checklist
|
|
3
|
+
about: Pre-launch checks to complete before going to production
|
|
4
|
+
title: "Launch checklist"
|
|
5
|
+
labels: launch
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<!-- Tick items as you go. Don't close this issue until every box is checked or explicitly marked N/A with a reason. -->
|
|
10
|
+
|
|
11
|
+
## Metadata & SEO
|
|
12
|
+
|
|
13
|
+
- [ ] Favicon added (`favicon.ico` + SVG).
|
|
14
|
+
- [ ] `<meta name="theme-color">` added.
|
|
15
|
+
- [ ] `<html lang="…">` is set correctly.
|
|
16
|
+
- [ ] Every route has a unique `<title>` and `<meta name="description">`.
|
|
17
|
+
- [ ] Every route has a canonical URL: `<link rel="canonical" href="…">`.
|
|
18
|
+
- [ ] Open Graph and Twitter tags are added (globally in `index.html` or per route). Use absolute URLs for `og:url` and `og:image`:
|
|
19
|
+
|
|
20
|
+
```html
|
|
21
|
+
<meta property="og:type" content="website" />
|
|
22
|
+
<meta property="og:site_name" content="SITE_NAME" />
|
|
23
|
+
<meta property="og:title" content="TITLE" />
|
|
24
|
+
<meta property="og:description" content="DESCRIPTION" />
|
|
25
|
+
<meta property="og:url" content="https://example.com/page" />
|
|
26
|
+
<meta property="og:image" content="https://example.com/og-image.png" />
|
|
27
|
+
<meta property="og:image:width" content="1200" />
|
|
28
|
+
<meta property="og:image:height" content="630" />
|
|
29
|
+
<meta property="og:image:alt" content="IMAGE_ALT_TEXT" />
|
|
30
|
+
<meta name="twitter:card" content="summary_large_image" />
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
- [ ] Social previews verified with a preview tool (e.g. opengraph.xyz, LinkedIn Post Inspector).
|
|
34
|
+
- [ ] `robots.txt` and `sitemap.xml` are in place.
|
|
35
|
+
- [ ] `<meta name="robots" content="noindex">` is added to routes that should not be indexed for search.
|
|
36
|
+
- [ ] Production is indexable (no leftover `noindex`), and staging is **not** indexable.
|
|
37
|
+
- [ ] `apple-touch-icon` (180×180) added - only needed for site which the users might "install".
|
|
38
|
+
- [ ] `site.webmanifest` added - only needed for site which the users might "install".
|
|
39
|
+
|
|
40
|
+
## Functionality & QA
|
|
41
|
+
|
|
42
|
+
- [ ] All routes load, including on direct visit or refresh (host has SPA fallback routing).
|
|
43
|
+
- [ ] A custom 404 page exists, and React error boundaries catch runtime errors.
|
|
44
|
+
- [ ] No errors or warnings in the browser console.
|
|
45
|
+
- [ ] All forms, links and external integrations work in production.
|
|
46
|
+
- [ ] Design QA is complete and signed off.
|
|
47
|
+
- [ ] The layout works on all viewport widths from 360px up. At minimum, check 360, 768, 1024 and 1440px.
|
|
48
|
+
- [ ] Tested in the latest Chrome, Firefox, Edge and Safari.
|
|
49
|
+
|
|
50
|
+
## Performance
|
|
51
|
+
|
|
52
|
+
- [ ] Initial JS on first page load is ≤ 175 KB gzipped.
|
|
53
|
+
- [ ] Main CSS file is ≤ 50 KB gzipped.
|
|
54
|
+
- [ ] Images are optimised (WebP/AVIF, correctly sized, ≤ 75 KB each, lazy-loaded below the fold).
|
|
55
|
+
- [ ] Fonts are subset and preloaded, with `font-display: swap`.
|
|
56
|
+
- [ ] Lighthouse scores (run in incognito against production):
|
|
57
|
+
|
|
58
|
+
| Category | Desktop | Mobile |
|
|
59
|
+
|----------------|---------|--------|
|
|
60
|
+
| Performance | ≥ 90 | ≥ 70 |
|
|
61
|
+
| Accessibility | ≥ 90 | ≥ 90 |
|
|
62
|
+
| Best Practices | ≥ 90 | ≥ 90 |
|
|
63
|
+
| SEO | ≥ 90 | ≥ 90 |
|
|
64
|
+
|
|
65
|
+
## Security & infrastructure
|
|
66
|
+
|
|
67
|
+
- [ ] `npm audit` shows no high or critical vulnerabilities.
|
|
68
|
+
- [ ] `npm audit --omit=dev` shows no vulnerabilities.
|
|
69
|
+
- [ ] No secrets or private API keys in the client bundle.
|
|
70
|
+
|
|
71
|
+
## Analytics & privacy
|
|
72
|
+
|
|
73
|
+
- [ ] Google Analytics and/or Microsoft Clarity are installed and events are confirmed arriving from production.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
This is a React + TypeScript + Vite project powered by Tailwind CSS, and the UNDP Design System, bootstrapped with [@undp/create-app](https://www.npmjs.com/package/@undp/create-app).
|
|
2
2
|
|
|
3
3
|
It includes:
|
|
4
|
+
|
|
4
5
|
* React 19.x with React compiler
|
|
5
6
|
* UNDP Design System
|
|
6
7
|
* Data fetching with [TanStack Query](https://tanstack.com/query)
|
|
@@ -71,22 +72,69 @@ Data fetching is powered by [TanStack Query](https://tanstack.com/query) for eff
|
|
|
71
72
|
|
|
72
73
|
To embed the visualization on an external page, include:
|
|
73
74
|
|
|
74
|
-
|
|
75
|
+
### Option 1: Iframe
|
|
76
|
+
|
|
77
|
+
__HTML Placeholder__
|
|
75
78
|
|
|
76
79
|
```html
|
|
77
|
-
<
|
|
80
|
+
<iframe
|
|
81
|
+
id="my-embed"
|
|
82
|
+
src="<url of the app>"
|
|
83
|
+
style="width: 100%; border: 0; display: block;"
|
|
84
|
+
scrolling="no"
|
|
85
|
+
/>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
__Required `<script>`__
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
<script>
|
|
92
|
+
var iframe = document.getElementById('my-embed');
|
|
93
|
+
window.addEventListener('message', function (e) {
|
|
94
|
+
if (e.origin !== 'APP_URL') return;
|
|
95
|
+
if (e.source !== iframe.contentWindow) return;
|
|
96
|
+
if (e.data && e.data.type === 'iframe-height') {
|
|
97
|
+
iframe.style.height = e.data.height + 'px';
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
</script>
|
|
78
101
|
```
|
|
79
102
|
|
|
80
|
-
|
|
103
|
+
_This script listens for height messages from the embedded web app and resizes the iframe to match its content, so the app displays without an inner scrollbar._
|
|
81
104
|
|
|
105
|
+
### Option 2: Embed in the page (Worst performance better UX)
|
|
106
|
+
|
|
107
|
+
__HTML Placeholder__
|
|
108
|
+
|
|
109
|
+
```html
|
|
110
|
+
<div id="root"></div>
|
|
82
111
|
```
|
|
112
|
+
|
|
113
|
+
__Required `<script>` and `<link>` tags__
|
|
114
|
+
|
|
115
|
+
```html
|
|
83
116
|
<link rel="dns-prefetch" href="{{Visualization URL}}">
|
|
84
117
|
<script defer="defer" type="module" src="{{Visualization URL}}/index.js"></script>
|
|
85
|
-
<link rel="modulepreload" crossorigin href="{{Visualization URL}}/react-{{hash}}.js">
|
|
86
|
-
<link rel="modulepreload" crossorigin href="{{Visualization URL}}/undp-{{hash}}.js">
|
|
87
118
|
<link rel="stylesheet" href="{{Visualization URL}}/style.css"></link>
|
|
88
119
|
```
|
|
89
120
|
|
|
121
|
+
## ✅ Launch Checklist
|
|
122
|
+
|
|
123
|
+
Before deploying to production, complete the launch checklist. It covers metadata and SEO, analytics, QA, accessibility, performance, security headers and caching.
|
|
124
|
+
|
|
125
|
+
The checklist is set up as a GitHub issue template, so each launch gets its own tickable copy:
|
|
126
|
+
|
|
127
|
+
1. Go to **Issues → New issue** in this repository.
|
|
128
|
+
2. Select **Launch checklist**.
|
|
129
|
+
3. Assign yourself, and click **Create**.
|
|
130
|
+
4. Tick items off as you complete them. The issue list shows progress (e.g. "7 of 32 tasks").
|
|
131
|
+
|
|
132
|
+
Or open it directly: [Create launch checklist issue](../../issues/new?template=launch-checklist.md)
|
|
133
|
+
|
|
134
|
+
Don't close the issue until every item is checked, or marked N/A with a reason.
|
|
135
|
+
|
|
136
|
+
The template lives in `.github/ISSUE_TEMPLATE/launch-checklist.md`.
|
|
137
|
+
|
|
90
138
|
## 📬 Contact us
|
|
91
139
|
|
|
92
140
|
For questions or feedback, contact us at [data@undp.org](mailto:data@undp.org).
|