Skip to content

Commit 8afb4e2

Browse files
⚑ perf: Use nextjs pwa feat to gen manifest file (lobehub#4042)
* ⚑ perf: Use nextjs pwa feat to gen manifest file * πŸ› fix: Fix review problem * βœ… test: Add test * πŸ’„ style: Update next config * πŸ› fix: Fix test config * πŸ’„ style: Update layout
1 parent d3aa60a commit 8afb4e2

File tree

15 files changed

+729
-176
lines changed

15 files changed

+729
-176
lines changed

β€Žnext.config.mjs

+46-1
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,19 @@ const nextConfig = {
101101
],
102102
source: '/apple-touch-icon.png',
103103
},
104+
{
105+
headers: [
106+
{
107+
key: 'Content-Type',
108+
value: 'application/javascript; charset=utf-8',
109+
},
110+
{
111+
key: 'Content-Security-Policy',
112+
value: "default-src 'self'; script-src 'self'",
113+
},
114+
],
115+
source: '/sw.js',
116+
},
104117
];
105118
},
106119

@@ -113,10 +126,42 @@ const nextConfig = {
113126
source: '/sitemap.xml',
114127
},
115128
{
116-
destination: '/discover',
129+
destination: '/manifest.webmanifest',
130+
permanent: true,
131+
source: '/manifest.json',
132+
},
133+
{
134+
destination: '/discover/assistant/:slug',
135+
has: [
136+
{
137+
key: 'agent',
138+
type: 'query',
139+
value: '(?<slug>.*)',
140+
},
141+
],
117142
permanent: true,
118143
source: '/market',
119144
},
145+
{
146+
destination: '/discover/assistants',
147+
permanent: true,
148+
source: '/discover/assistant',
149+
},
150+
{
151+
destination: '/discover/models',
152+
permanent: true,
153+
source: '/discover/model',
154+
},
155+
{
156+
destination: '/discover/plugins',
157+
permanent: true,
158+
source: '/discover/plugin',
159+
},
160+
{
161+
destination: '/discover/providers',
162+
permanent: true,
163+
source: '/discover/provider',
164+
},
120165
{
121166
destination: '/settings/common',
122167
permanent: true,

β€Žpublic/manifest.json

-166
This file was deleted.

β€Žsrc/app/(main)/discover/(detail)/_layout/Desktop.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@ const Layout = ({ children }: PropsWithChildren) => {
99
align={'center'}
1010
flex={1}
1111
padding={24}
12-
style={{ overflowX: 'hidden', overflowY: 'scroll', position: 'relative' }}
12+
style={{ overflowX: 'hidden', overflowY: 'auto', position: 'relative' }}
1313
width={'100%'}
1414
>
15-
<Flexbox gap={24} style={{ maxWidth: MAX_WIDTH, position: 'relative' }} width={'100%'}>
15+
<Flexbox
16+
gap={24}
17+
style={{ maxWidth: MAX_WIDTH, minHeight: '100%', position: 'relative' }}
18+
width={'100%'}
19+
>
1620
{children}
1721
</Flexbox>
1822
</Flexbox>

β€Žsrc/app/(main)/discover/(detail)/assistant/[slug]/page.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const generateMetadata = async ({ params, searchParams }: Props) => {
2727

2828
const discoverService = new DiscoverService();
2929
const data = await discoverService.getAssistantById(locale, identifier);
30-
if (!data) return notFound();
30+
if (!data) return;
3131

3232
const { meta, createdAt, homepage, author } = data;
3333

β€Žsrc/app/(main)/discover/(detail)/model/[...slugs]/page.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const generateMetadata = async ({ params, searchParams }: Props) => {
2727

2828
const discoverService = new DiscoverService();
2929
const data = await discoverService.getModelById(locale, identifier);
30-
if (!data) return notFound();
30+
if (!data) return;
3131

3232
const { meta, createdAt, providers } = data;
3333

β€Žsrc/app/(main)/discover/(detail)/plugin/[slug]/page.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export const generateMetadata = async ({ params, searchParams }: Props) => {
2424

2525
const discoverService = new DiscoverService();
2626
const data = await discoverService.getPluginById(locale, identifier);
27-
if (!data) return notFound();
27+
if (!data) return;
2828

2929
const { meta, createdAt, homepage, author } = data;
3030

β€Žsrc/app/(main)/discover/(detail)/provider/[slug]/page.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const generateMetadata = async ({ params, searchParams }: Props) => {
2727

2828
const discoverService = new DiscoverService();
2929
const data = await discoverService.getProviderById(locale, identifier);
30-
if (!data) return notFound();
30+
if (!data) return;
3131

3232
const { meta, createdAt, models } = data;
3333

β€Žsrc/app/manifest.ts

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { kebabCase } from 'lodash-es';
2+
import type { MetadataRoute } from 'next';
3+
4+
import { BRANDING_LOGO_URL, BRANDING_NAME } from '@/const/branding';
5+
import { manifestModule } from '@/server/manifest';
6+
import { translation } from '@/server/translation';
7+
8+
const manifest = async (): Promise<MetadataRoute.Manifest | any> => {
9+
const { t } = await translation('metadata');
10+
11+
return manifestModule.generate({
12+
description: t('chat.description', { appName: BRANDING_NAME }),
13+
icons: [
14+
{
15+
purpose: 'any',
16+
sizes: '192x192',
17+
url: '/icons/icon-192x192.png',
18+
},
19+
{
20+
purpose: 'maskable',
21+
sizes: '192x192',
22+
url: '/icons/icon-192x192.maskable.png',
23+
},
24+
{
25+
purpose: 'any',
26+
sizes: '512x512',
27+
url: '/icons/icon-512x512.png',
28+
},
29+
{
30+
purpose: 'maskable',
31+
sizes: '512x512',
32+
url: '/icons/icon-512x512.maskable.png',
33+
},
34+
],
35+
id: kebabCase(BRANDING_NAME),
36+
name: BRANDING_NAME,
37+
screenshots: BRANDING_LOGO_URL
38+
? []
39+
: [
40+
{
41+
form_factor: 'narrow',
42+
url: '/screenshots/shot-1.mobile.png',
43+
},
44+
{
45+
form_factor: 'narrow',
46+
url: '/screenshots/shot-2.mobile.png',
47+
},
48+
{
49+
form_factor: 'narrow',
50+
sizes: '640x1138',
51+
52+
url: '/screenshots/shot-3.mobile.png',
53+
},
54+
{
55+
form_factor: 'narrow',
56+
url: '/screenshots/shot-4.mobile.png',
57+
},
58+
{
59+
form_factor: 'narrow',
60+
url: '/screenshots/shot-5.mobile.png',
61+
},
62+
{
63+
form_factor: 'wide',
64+
url: '/screenshots/shot-1.desktop.png',
65+
},
66+
{
67+
form_factor: 'wide',
68+
url: '/screenshots/shot-2.desktop.png',
69+
},
70+
{
71+
form_factor: 'wide',
72+
url: '/screenshots/shot-3.desktop.png',
73+
},
74+
{
75+
form_factor: 'wide',
76+
url: '/screenshots/shot-4.desktop.png',
77+
},
78+
{
79+
form_factor: 'wide',
80+
url: '/screenshots/shot-5.desktop.png',
81+
},
82+
],
83+
});
84+
};
85+
86+
export default manifest;

β€Žsrc/features/PWAInstall/index.tsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,11 @@ const PWAInstall = memo(() => {
6868

6969
if (isPWA) return null;
7070
return (
71-
<PWA description={t('chat.description', { appName: BRANDING_NAME })} id={PWA_INSTALL_ID} />
71+
<PWA
72+
description={t('chat.description', { appName: BRANDING_NAME })}
73+
id={PWA_INSTALL_ID}
74+
manifest-url={'/manifest.webmanifest'}
75+
/>
7276
);
7377
});
7478

0 commit comments

Comments
Β (0)