@windrun-huaiin/third-ui 31.3.0 → 31.3.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/dist/fuma/mdx/toc-footer-wrapper.js +4 -1
- package/dist/fuma/mdx/toc-footer-wrapper.mjs +4 -1
- package/dist/lib/seo-metadata.d.ts +20 -1
- package/dist/lib/seo-metadata.js +116 -10
- package/dist/lib/seo-metadata.mjs +114 -11
- package/dist/main/cta.js +1 -1
- package/dist/main/cta.mjs +1 -1
- package/dist/main/section-layout.d.ts +1 -1
- package/dist/main/section-layout.js +1 -1
- package/dist/main/section-layout.mjs +1 -1
- package/package.json +2 -2
- package/src/fuma/mdx/toc-footer-wrapper.tsx +5 -1
- package/src/lib/seo-metadata.ts +198 -13
- package/src/main/cta.tsx +4 -5
- package/src/main/section-layout.ts +1 -1
|
@@ -4,9 +4,12 @@
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var tocBase = require('./toc-base.js');
|
|
6
6
|
|
|
7
|
+
function joinUrlPath(baseUrl, path) {
|
|
8
|
+
return `${baseUrl.replace(/\/+$/, '')}/${path.replace(/^\/+/, '')}`;
|
|
9
|
+
}
|
|
7
10
|
function TocFooterWrapper({ lastModified, editPath, githubBaseUrl, copyButtonComponent }) {
|
|
8
11
|
const showEdit = githubBaseUrl && editPath;
|
|
9
|
-
return (jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-2 items-start m-4", children: [jsxRuntime.jsx(tocBase.LastUpdatedDate, { date: lastModified }), copyButtonComponent, showEdit && jsxRuntime.jsx(tocBase.EditOnGitHub, { url:
|
|
12
|
+
return (jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-2 items-start m-4", children: [jsxRuntime.jsx(tocBase.LastUpdatedDate, { date: lastModified }), copyButtonComponent, showEdit && jsxRuntime.jsx(tocBase.EditOnGitHub, { url: joinUrlPath(githubBaseUrl, editPath) })] }));
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
exports.TocFooterWrapper = TocFooterWrapper;
|
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { LastUpdatedDate, EditOnGitHub } from './toc-base.mjs';
|
|
4
4
|
|
|
5
|
+
function joinUrlPath(baseUrl, path) {
|
|
6
|
+
return `${baseUrl.replace(/\/+$/, '')}/${path.replace(/^\/+/, '')}`;
|
|
7
|
+
}
|
|
5
8
|
function TocFooterWrapper({ lastModified, editPath, githubBaseUrl, copyButtonComponent }) {
|
|
6
9
|
const showEdit = githubBaseUrl && editPath;
|
|
7
|
-
return (jsxs("div", { className: "flex flex-col gap-y-2 items-start m-4", children: [jsx(LastUpdatedDate, { date: lastModified }), copyButtonComponent, showEdit && jsx(EditOnGitHub, { url:
|
|
10
|
+
return (jsxs("div", { className: "flex flex-col gap-y-2 items-start m-4", children: [jsx(LastUpdatedDate, { date: lastModified }), copyButtonComponent, showEdit && jsx(EditOnGitHub, { url: joinUrlPath(githubBaseUrl, editPath) })] }));
|
|
8
11
|
}
|
|
9
12
|
|
|
10
13
|
export { TocFooterWrapper };
|
|
@@ -6,5 +6,24 @@ export interface CreateLocalizedSiteMetadataOptions {
|
|
|
6
6
|
defaultLocale: string;
|
|
7
7
|
localePrefixAsNeeded: boolean;
|
|
8
8
|
}
|
|
9
|
-
export
|
|
9
|
+
export interface LocalizedPageUrlOptions extends CreateLocalizedSiteMetadataOptions {
|
|
10
|
+
pathname: string;
|
|
11
|
+
}
|
|
12
|
+
export type LocalizedSiteMetadata = Pick<Metadata, 'title' | 'description' | 'keywords' | 'icons' | 'openGraph' | 'twitter'>;
|
|
13
|
+
export type LocalizedPageMetadataOverrides = Pick<Metadata, 'title' | 'description' | 'keywords' | 'icons' | 'openGraph' | 'twitter' | 'robots' | 'authors' | 'creator' | 'publisher' | 'category'>;
|
|
14
|
+
export interface CreateLocalizedPageMetadataOptions {
|
|
15
|
+
url: LocalizedPageUrlOptions;
|
|
16
|
+
site?: LocalizedSiteMetadata;
|
|
17
|
+
page?: LocalizedPageMetadataOverrides;
|
|
18
|
+
}
|
|
19
|
+
export interface LocalizedNamespaceMetadataOptions {
|
|
20
|
+
url: LocalizedPageUrlOptions;
|
|
21
|
+
namespace: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function resolveMetadataOverrides(options: {
|
|
24
|
+
locale: string;
|
|
25
|
+
namespace: string;
|
|
26
|
+
}): Promise<LocalizedPageMetadataOverrides>;
|
|
10
27
|
export declare function createLocalizedSiteMetadata(options: CreateLocalizedSiteMetadataOptions): Promise<LocalizedSiteMetadata>;
|
|
28
|
+
export declare function createLocalizedPageMetadata(options: CreateLocalizedPageMetadataOptions): Metadata;
|
|
29
|
+
export declare function createLocalizedMetadata(options: LocalizedNamespaceMetadataOptions): Promise<Metadata>;
|
package/dist/lib/seo-metadata.js
CHANGED
|
@@ -11,24 +11,130 @@ const DEFAULT_SITE_ICONS = [
|
|
|
11
11
|
{ rel: 'apple-touch-icon', sizes: '180x180', url: '/favicon-180x180.png' },
|
|
12
12
|
{ rel: 'android-chrome', sizes: '512x512', url: '/favicon-512x512.png' },
|
|
13
13
|
];
|
|
14
|
+
function buildAlternateUrls(options) {
|
|
15
|
+
const { baseUrl, defaultLocale, locale, localePrefixAsNeeded, locales, pathname } = options;
|
|
16
|
+
const canonicalPath = utils.getAsNeededLocalizedUrl(locale, pathname, localePrefixAsNeeded, defaultLocale);
|
|
17
|
+
const canonical = `${baseUrl}${canonicalPath}`;
|
|
18
|
+
const languages = Object.fromEntries(locales.map((siteLocale) => [
|
|
19
|
+
siteLocale,
|
|
20
|
+
`${baseUrl}${utils.getAsNeededLocalizedUrl(siteLocale, pathname, localePrefixAsNeeded, defaultLocale)}`,
|
|
21
|
+
]));
|
|
22
|
+
return {
|
|
23
|
+
canonical,
|
|
24
|
+
languages,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function getOptionalTranslation(t, key) {
|
|
28
|
+
return t.has(key) ? t(key) : undefined;
|
|
29
|
+
}
|
|
30
|
+
function getNestedTranslation(t, key, fallback) {
|
|
31
|
+
var _a;
|
|
32
|
+
return (_a = getOptionalTranslation(t, key)) !== null && _a !== void 0 ? _a : fallback;
|
|
33
|
+
}
|
|
34
|
+
function getAbsoluteUrl(baseUrl, value) {
|
|
35
|
+
if (/^https?:\/\//i.test(value)) {
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
|
|
39
|
+
const normalizedPath = value.startsWith('/') ? value : `/${value}`;
|
|
40
|
+
return `${normalizedBaseUrl}${normalizedPath}`;
|
|
41
|
+
}
|
|
42
|
+
function getImageUrls(baseUrl, value) {
|
|
43
|
+
if (!value)
|
|
44
|
+
return undefined;
|
|
45
|
+
const urls = Array.isArray(value) ? value : [value];
|
|
46
|
+
const cleaned = urls.map((item) => item.trim()).filter(Boolean);
|
|
47
|
+
return cleaned.length > 0
|
|
48
|
+
? cleaned.map((url) => ({ url: getAbsoluteUrl(baseUrl, url) }))
|
|
49
|
+
: undefined;
|
|
50
|
+
}
|
|
51
|
+
function getEnvText(value) {
|
|
52
|
+
const trimmed = value === null || value === void 0 ? void 0 : value.trim();
|
|
53
|
+
return trimmed ? trimmed : undefined;
|
|
54
|
+
}
|
|
55
|
+
function resolveMetadataOverrides(options) {
|
|
56
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
57
|
+
var _a, _b, _c;
|
|
58
|
+
const { locale, namespace } = options;
|
|
59
|
+
const t = yield server.getTranslations({ locale, namespace });
|
|
60
|
+
const ogType = getEnvText(process.env.NEXT_PUBLIC_OG_TYPE);
|
|
61
|
+
const xSiteName = getEnvText(process.env.NEXT_PUBLIC_X_SITE_NAME);
|
|
62
|
+
const baseUrl = (_a = getEnvText(process.env.NEXT_PUBLIC_BASE_URL)) !== null && _a !== void 0 ? _a : '';
|
|
63
|
+
const title = getOptionalTranslation(t, 'title');
|
|
64
|
+
const description = getOptionalTranslation(t, 'description');
|
|
65
|
+
return {
|
|
66
|
+
title,
|
|
67
|
+
description,
|
|
68
|
+
keywords: getOptionalTranslation(t, 'keywords'),
|
|
69
|
+
openGraph: Object.assign(Object.assign({}, (ogType ? { type: ogType } : {})), { title: getNestedTranslation(t, 'openGraph.title', title), description: getNestedTranslation(t, 'openGraph.description', description), images: getImageUrls(baseUrl, (_b = getOptionalTranslation(t, 'openGraph.image')) !== null && _b !== void 0 ? _b : getOptionalTranslation(t, 'openGraph.images')) }),
|
|
70
|
+
twitter: Object.assign(Object.assign({}, (xSiteName ? { site: xSiteName } : {})), { title: getNestedTranslation(t, 'twitter.title', title), description: getNestedTranslation(t, 'twitter.description', description), images: getImageUrls(baseUrl, (_c = getOptionalTranslation(t, 'twitter.image')) !== null && _c !== void 0 ? _c : getOptionalTranslation(t, 'twitter.images')) }),
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
}
|
|
14
74
|
function createLocalizedSiteMetadata(options) {
|
|
15
75
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
16
|
-
|
|
76
|
+
var _a;
|
|
77
|
+
const { locale } = options;
|
|
17
78
|
const t = yield server.getTranslations({ locale, namespace: 'home' });
|
|
79
|
+
const ogType = getEnvText(process.env.NEXT_PUBLIC_OG_TYPE);
|
|
80
|
+
const xSiteName = getEnvText(process.env.NEXT_PUBLIC_X_SITE_NAME);
|
|
81
|
+
const baseUrl = (_a = getEnvText(process.env.NEXT_PUBLIC_BASE_URL)) !== null && _a !== void 0 ? _a : '';
|
|
82
|
+
const title = t('webTitle');
|
|
83
|
+
const description = t('webDescription');
|
|
84
|
+
const ogTitle = getNestedTranslation(t, 'openGraph.title', title);
|
|
85
|
+
const ogDescription = getNestedTranslation(t, 'openGraph.description', description);
|
|
86
|
+
const twitterTitle = getNestedTranslation(t, 'twitter.title', title);
|
|
87
|
+
const twitterDescription = getNestedTranslation(t, 'twitter.description', description);
|
|
18
88
|
return {
|
|
19
|
-
title
|
|
20
|
-
description
|
|
89
|
+
title,
|
|
90
|
+
description,
|
|
21
91
|
keywords: t('keywords'),
|
|
22
|
-
alternates: {
|
|
23
|
-
canonical: `${baseUrl}${utils.getAsNeededLocalizedUrl(locale, '/', localePrefixAsNeeded, defaultLocale)}`,
|
|
24
|
-
languages: Object.fromEntries(locales.map((siteLocale) => [
|
|
25
|
-
siteLocale,
|
|
26
|
-
`${baseUrl}${utils.getAsNeededLocalizedUrl(siteLocale, '/', localePrefixAsNeeded, defaultLocale)}`,
|
|
27
|
-
])),
|
|
28
|
-
},
|
|
29
92
|
icons: DEFAULT_SITE_ICONS,
|
|
93
|
+
openGraph: Object.assign(Object.assign({}, (ogType ? { type: ogType } : {})), { title: ogTitle, description: ogDescription, images: getImageUrls(baseUrl, getOptionalTranslation(t, 'openGraph.image')) }),
|
|
94
|
+
twitter: Object.assign(Object.assign({}, (xSiteName ? { site: xSiteName } : {})), { title: twitterTitle, description: twitterDescription, images: getImageUrls(baseUrl, getOptionalTranslation(t, 'twitter.image')) }),
|
|
30
95
|
};
|
|
31
96
|
});
|
|
32
97
|
}
|
|
98
|
+
function createLocalizedPageMetadata(options) {
|
|
99
|
+
var _a, _b, _c, _d;
|
|
100
|
+
const { page, site, url } = options;
|
|
101
|
+
const { baseUrl } = url;
|
|
102
|
+
const alternates = buildAlternateUrls(url);
|
|
103
|
+
const openGraph = Object.assign(Object.assign(Object.assign({}, site === null || site === void 0 ? void 0 : site.openGraph), page === null || page === void 0 ? void 0 : page.openGraph), { url: alternates.canonical });
|
|
104
|
+
const twitter = Object.assign(Object.assign({}, site === null || site === void 0 ? void 0 : site.twitter), page === null || page === void 0 ? void 0 : page.twitter);
|
|
105
|
+
return {
|
|
106
|
+
metadataBase: new URL(baseUrl),
|
|
107
|
+
title: (_a = page === null || page === void 0 ? void 0 : page.title) !== null && _a !== void 0 ? _a : site === null || site === void 0 ? void 0 : site.title,
|
|
108
|
+
description: (_b = page === null || page === void 0 ? void 0 : page.description) !== null && _b !== void 0 ? _b : site === null || site === void 0 ? void 0 : site.description,
|
|
109
|
+
keywords: (_c = page === null || page === void 0 ? void 0 : page.keywords) !== null && _c !== void 0 ? _c : site === null || site === void 0 ? void 0 : site.keywords,
|
|
110
|
+
icons: (_d = page === null || page === void 0 ? void 0 : page.icons) !== null && _d !== void 0 ? _d : site === null || site === void 0 ? void 0 : site.icons,
|
|
111
|
+
openGraph,
|
|
112
|
+
twitter,
|
|
113
|
+
robots: page === null || page === void 0 ? void 0 : page.robots,
|
|
114
|
+
authors: page === null || page === void 0 ? void 0 : page.authors,
|
|
115
|
+
creator: page === null || page === void 0 ? void 0 : page.creator,
|
|
116
|
+
publisher: page === null || page === void 0 ? void 0 : page.publisher,
|
|
117
|
+
category: page === null || page === void 0 ? void 0 : page.category,
|
|
118
|
+
alternates,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function createLocalizedMetadata(options) {
|
|
122
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
123
|
+
const { namespace, url } = options;
|
|
124
|
+
const site = yield createLocalizedSiteMetadata(url);
|
|
125
|
+
const page = yield resolveMetadataOverrides({
|
|
126
|
+
locale: url.locale,
|
|
127
|
+
namespace,
|
|
128
|
+
});
|
|
129
|
+
return createLocalizedPageMetadata({
|
|
130
|
+
url,
|
|
131
|
+
site,
|
|
132
|
+
page,
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
}
|
|
33
136
|
|
|
137
|
+
exports.createLocalizedMetadata = createLocalizedMetadata;
|
|
138
|
+
exports.createLocalizedPageMetadata = createLocalizedPageMetadata;
|
|
34
139
|
exports.createLocalizedSiteMetadata = createLocalizedSiteMetadata;
|
|
140
|
+
exports.resolveMetadataOverrides = resolveMetadataOverrides;
|
|
@@ -9,24 +9,127 @@ const DEFAULT_SITE_ICONS = [
|
|
|
9
9
|
{ rel: 'apple-touch-icon', sizes: '180x180', url: '/favicon-180x180.png' },
|
|
10
10
|
{ rel: 'android-chrome', sizes: '512x512', url: '/favicon-512x512.png' },
|
|
11
11
|
];
|
|
12
|
+
function buildAlternateUrls(options) {
|
|
13
|
+
const { baseUrl, defaultLocale, locale, localePrefixAsNeeded, locales, pathname } = options;
|
|
14
|
+
const canonicalPath = getAsNeededLocalizedUrl(locale, pathname, localePrefixAsNeeded, defaultLocale);
|
|
15
|
+
const canonical = `${baseUrl}${canonicalPath}`;
|
|
16
|
+
const languages = Object.fromEntries(locales.map((siteLocale) => [
|
|
17
|
+
siteLocale,
|
|
18
|
+
`${baseUrl}${getAsNeededLocalizedUrl(siteLocale, pathname, localePrefixAsNeeded, defaultLocale)}`,
|
|
19
|
+
]));
|
|
20
|
+
return {
|
|
21
|
+
canonical,
|
|
22
|
+
languages,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function getOptionalTranslation(t, key) {
|
|
26
|
+
return t.has(key) ? t(key) : undefined;
|
|
27
|
+
}
|
|
28
|
+
function getNestedTranslation(t, key, fallback) {
|
|
29
|
+
var _a;
|
|
30
|
+
return (_a = getOptionalTranslation(t, key)) !== null && _a !== void 0 ? _a : fallback;
|
|
31
|
+
}
|
|
32
|
+
function getAbsoluteUrl(baseUrl, value) {
|
|
33
|
+
if (/^https?:\/\//i.test(value)) {
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
|
|
37
|
+
const normalizedPath = value.startsWith('/') ? value : `/${value}`;
|
|
38
|
+
return `${normalizedBaseUrl}${normalizedPath}`;
|
|
39
|
+
}
|
|
40
|
+
function getImageUrls(baseUrl, value) {
|
|
41
|
+
if (!value)
|
|
42
|
+
return undefined;
|
|
43
|
+
const urls = Array.isArray(value) ? value : [value];
|
|
44
|
+
const cleaned = urls.map((item) => item.trim()).filter(Boolean);
|
|
45
|
+
return cleaned.length > 0
|
|
46
|
+
? cleaned.map((url) => ({ url: getAbsoluteUrl(baseUrl, url) }))
|
|
47
|
+
: undefined;
|
|
48
|
+
}
|
|
49
|
+
function getEnvText(value) {
|
|
50
|
+
const trimmed = value === null || value === void 0 ? void 0 : value.trim();
|
|
51
|
+
return trimmed ? trimmed : undefined;
|
|
52
|
+
}
|
|
53
|
+
function resolveMetadataOverrides(options) {
|
|
54
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
+
var _a, _b, _c;
|
|
56
|
+
const { locale, namespace } = options;
|
|
57
|
+
const t = yield getTranslations({ locale, namespace });
|
|
58
|
+
const ogType = getEnvText(process.env.NEXT_PUBLIC_OG_TYPE);
|
|
59
|
+
const xSiteName = getEnvText(process.env.NEXT_PUBLIC_X_SITE_NAME);
|
|
60
|
+
const baseUrl = (_a = getEnvText(process.env.NEXT_PUBLIC_BASE_URL)) !== null && _a !== void 0 ? _a : '';
|
|
61
|
+
const title = getOptionalTranslation(t, 'title');
|
|
62
|
+
const description = getOptionalTranslation(t, 'description');
|
|
63
|
+
return {
|
|
64
|
+
title,
|
|
65
|
+
description,
|
|
66
|
+
keywords: getOptionalTranslation(t, 'keywords'),
|
|
67
|
+
openGraph: Object.assign(Object.assign({}, (ogType ? { type: ogType } : {})), { title: getNestedTranslation(t, 'openGraph.title', title), description: getNestedTranslation(t, 'openGraph.description', description), images: getImageUrls(baseUrl, (_b = getOptionalTranslation(t, 'openGraph.image')) !== null && _b !== void 0 ? _b : getOptionalTranslation(t, 'openGraph.images')) }),
|
|
68
|
+
twitter: Object.assign(Object.assign({}, (xSiteName ? { site: xSiteName } : {})), { title: getNestedTranslation(t, 'twitter.title', title), description: getNestedTranslation(t, 'twitter.description', description), images: getImageUrls(baseUrl, (_c = getOptionalTranslation(t, 'twitter.image')) !== null && _c !== void 0 ? _c : getOptionalTranslation(t, 'twitter.images')) }),
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
}
|
|
12
72
|
function createLocalizedSiteMetadata(options) {
|
|
13
73
|
return __awaiter(this, void 0, void 0, function* () {
|
|
14
|
-
|
|
74
|
+
var _a;
|
|
75
|
+
const { locale } = options;
|
|
15
76
|
const t = yield getTranslations({ locale, namespace: 'home' });
|
|
77
|
+
const ogType = getEnvText(process.env.NEXT_PUBLIC_OG_TYPE);
|
|
78
|
+
const xSiteName = getEnvText(process.env.NEXT_PUBLIC_X_SITE_NAME);
|
|
79
|
+
const baseUrl = (_a = getEnvText(process.env.NEXT_PUBLIC_BASE_URL)) !== null && _a !== void 0 ? _a : '';
|
|
80
|
+
const title = t('webTitle');
|
|
81
|
+
const description = t('webDescription');
|
|
82
|
+
const ogTitle = getNestedTranslation(t, 'openGraph.title', title);
|
|
83
|
+
const ogDescription = getNestedTranslation(t, 'openGraph.description', description);
|
|
84
|
+
const twitterTitle = getNestedTranslation(t, 'twitter.title', title);
|
|
85
|
+
const twitterDescription = getNestedTranslation(t, 'twitter.description', description);
|
|
16
86
|
return {
|
|
17
|
-
title
|
|
18
|
-
description
|
|
87
|
+
title,
|
|
88
|
+
description,
|
|
19
89
|
keywords: t('keywords'),
|
|
20
|
-
alternates: {
|
|
21
|
-
canonical: `${baseUrl}${getAsNeededLocalizedUrl(locale, '/', localePrefixAsNeeded, defaultLocale)}`,
|
|
22
|
-
languages: Object.fromEntries(locales.map((siteLocale) => [
|
|
23
|
-
siteLocale,
|
|
24
|
-
`${baseUrl}${getAsNeededLocalizedUrl(siteLocale, '/', localePrefixAsNeeded, defaultLocale)}`,
|
|
25
|
-
])),
|
|
26
|
-
},
|
|
27
90
|
icons: DEFAULT_SITE_ICONS,
|
|
91
|
+
openGraph: Object.assign(Object.assign({}, (ogType ? { type: ogType } : {})), { title: ogTitle, description: ogDescription, images: getImageUrls(baseUrl, getOptionalTranslation(t, 'openGraph.image')) }),
|
|
92
|
+
twitter: Object.assign(Object.assign({}, (xSiteName ? { site: xSiteName } : {})), { title: twitterTitle, description: twitterDescription, images: getImageUrls(baseUrl, getOptionalTranslation(t, 'twitter.image')) }),
|
|
28
93
|
};
|
|
29
94
|
});
|
|
30
95
|
}
|
|
96
|
+
function createLocalizedPageMetadata(options) {
|
|
97
|
+
var _a, _b, _c, _d;
|
|
98
|
+
const { page, site, url } = options;
|
|
99
|
+
const { baseUrl } = url;
|
|
100
|
+
const alternates = buildAlternateUrls(url);
|
|
101
|
+
const openGraph = Object.assign(Object.assign(Object.assign({}, site === null || site === void 0 ? void 0 : site.openGraph), page === null || page === void 0 ? void 0 : page.openGraph), { url: alternates.canonical });
|
|
102
|
+
const twitter = Object.assign(Object.assign({}, site === null || site === void 0 ? void 0 : site.twitter), page === null || page === void 0 ? void 0 : page.twitter);
|
|
103
|
+
return {
|
|
104
|
+
metadataBase: new URL(baseUrl),
|
|
105
|
+
title: (_a = page === null || page === void 0 ? void 0 : page.title) !== null && _a !== void 0 ? _a : site === null || site === void 0 ? void 0 : site.title,
|
|
106
|
+
description: (_b = page === null || page === void 0 ? void 0 : page.description) !== null && _b !== void 0 ? _b : site === null || site === void 0 ? void 0 : site.description,
|
|
107
|
+
keywords: (_c = page === null || page === void 0 ? void 0 : page.keywords) !== null && _c !== void 0 ? _c : site === null || site === void 0 ? void 0 : site.keywords,
|
|
108
|
+
icons: (_d = page === null || page === void 0 ? void 0 : page.icons) !== null && _d !== void 0 ? _d : site === null || site === void 0 ? void 0 : site.icons,
|
|
109
|
+
openGraph,
|
|
110
|
+
twitter,
|
|
111
|
+
robots: page === null || page === void 0 ? void 0 : page.robots,
|
|
112
|
+
authors: page === null || page === void 0 ? void 0 : page.authors,
|
|
113
|
+
creator: page === null || page === void 0 ? void 0 : page.creator,
|
|
114
|
+
publisher: page === null || page === void 0 ? void 0 : page.publisher,
|
|
115
|
+
category: page === null || page === void 0 ? void 0 : page.category,
|
|
116
|
+
alternates,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function createLocalizedMetadata(options) {
|
|
120
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
121
|
+
const { namespace, url } = options;
|
|
122
|
+
const site = yield createLocalizedSiteMetadata(url);
|
|
123
|
+
const page = yield resolveMetadataOverrides({
|
|
124
|
+
locale: url.locale,
|
|
125
|
+
namespace,
|
|
126
|
+
});
|
|
127
|
+
return createLocalizedPageMetadata({
|
|
128
|
+
url,
|
|
129
|
+
site,
|
|
130
|
+
page,
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
}
|
|
31
134
|
|
|
32
|
-
export { createLocalizedSiteMetadata };
|
|
135
|
+
export { createLocalizedMetadata, createLocalizedPageMetadata, createLocalizedSiteMetadata, resolveMetadataOverrides };
|
package/dist/main/cta.js
CHANGED
|
@@ -38,7 +38,7 @@ function CTA(_a) {
|
|
|
38
38
|
button: t('button'),
|
|
39
39
|
url: t('url')
|
|
40
40
|
};
|
|
41
|
-
return (jsxRuntime.jsx("section", { id: "cta", className: utils.cn(sectionLayout.responsiveSection, sectionClassName), children: jsxRuntime.jsx("div", { className: "\n third-ui-cta-surface\n relative overflow-hidden rounded-2xl border border-black/5 py-3 text-center shadow-sm\n animate-cta-gradient-wave\n sm:py-6 md:py-8\n dark:border-white/10 dark:shadow-none\n ", style: createCTAStyle(), children: jsxRuntime.jsxs("div", { className: "relative z-10 px-4 sm:px-6", children: [jsxRuntime.jsxs("h2", { className: "mb-6 text-3xl font-bold text-neutral-950 md:text-4xl dark:text-neutral-50", children: [data.title, " ", jsxRuntime.jsx("span", { className: lib.themeIconColor, children: data.eyesOn }), "?"] }), jsxRuntime.jsxs("
|
|
41
|
+
return (jsxRuntime.jsx("section", { id: "cta", className: utils.cn(sectionLayout.responsiveSection, sectionClassName), children: jsxRuntime.jsx("div", { className: "\n third-ui-cta-surface\n relative overflow-hidden rounded-2xl border border-black/5 py-3 text-center shadow-sm\n animate-cta-gradient-wave\n sm:py-6 md:py-8\n dark:border-white/10 dark:shadow-none\n ", style: createCTAStyle(), children: jsxRuntime.jsxs("div", { className: "relative z-10 px-4 sm:px-6", children: [jsxRuntime.jsxs("h2", { className: "mb-6 text-3xl font-bold text-neutral-950 md:text-4xl dark:text-neutral-50", children: [data.title, " ", jsxRuntime.jsx("span", { className: lib.themeIconColor, children: data.eyesOn }), "?"] }), jsxRuntime.jsxs("div", { className: "mx-auto mb-8 space-y-2 max-w-4xl text-base text-neutral-700 sm:text-xl dark:text-neutral-300", children: [jsxRuntime.jsx("p", { children: data.description1 }), jsxRuntime.jsx("p", { className: utils.cn(lib.themeIconColor, "text-xl sm:text-2xl"), children: data.description2 })] }), jsxRuntime.jsx(gradientButton.GradientButton, { title: data.button, href: data.url, align: "center" })] }) }) }));
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
44
|
|
package/dist/main/cta.mjs
CHANGED
|
@@ -36,7 +36,7 @@ function CTA(_a) {
|
|
|
36
36
|
button: t('button'),
|
|
37
37
|
url: t('url')
|
|
38
38
|
};
|
|
39
|
-
return (jsx("section", { id: "cta", className: cn(responsiveSection, sectionClassName), children: jsx("div", { className: "\n third-ui-cta-surface\n relative overflow-hidden rounded-2xl border border-black/5 py-3 text-center shadow-sm\n animate-cta-gradient-wave\n sm:py-6 md:py-8\n dark:border-white/10 dark:shadow-none\n ", style: createCTAStyle(), children: jsxs("div", { className: "relative z-10 px-4 sm:px-6", children: [jsxs("h2", { className: "mb-6 text-3xl font-bold text-neutral-950 md:text-4xl dark:text-neutral-50", children: [data.title, " ", jsx("span", { className: themeIconColor, children: data.eyesOn }), "?"] }), jsxs("
|
|
39
|
+
return (jsx("section", { id: "cta", className: cn(responsiveSection, sectionClassName), children: jsx("div", { className: "\n third-ui-cta-surface\n relative overflow-hidden rounded-2xl border border-black/5 py-3 text-center shadow-sm\n animate-cta-gradient-wave\n sm:py-6 md:py-8\n dark:border-white/10 dark:shadow-none\n ", style: createCTAStyle(), children: jsxs("div", { className: "relative z-10 px-4 sm:px-6", children: [jsxs("h2", { className: "mb-6 text-3xl font-bold text-neutral-950 md:text-4xl dark:text-neutral-50", children: [data.title, " ", jsx("span", { className: themeIconColor, children: data.eyesOn }), "?"] }), jsxs("div", { className: "mx-auto mb-8 space-y-2 max-w-4xl text-base text-neutral-700 sm:text-xl dark:text-neutral-300", children: [jsx("p", { children: data.description1 }), jsx("p", { className: cn(themeIconColor, "text-xl sm:text-2xl"), children: data.description2 })] }), jsx(GradientButton, { title: data.button, href: data.url, align: "center" })] }) }) }));
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const responsiveSection = "mx-auto max-w-6xl min-w-[calc(100vw-22rem)] px-4 py-10 sm:px-6 md:px-8 lg:px-10 scroll-mt-20";
|
|
1
|
+
export declare const responsiveSection = "mx-auto max-w-6xl min-w-[calc(100vw-22rem)] px-4 py-10 sm:px-6 md:px-8 lg:px-10 scroll-mt-20 w-full";
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
const sectionSpacing = "px-4 py-10 sm:px-6 md:px-8 lg:px-10 scroll-mt-20";
|
|
4
4
|
const wideWidth = "max-w-6xl min-w-[calc(100vw-22rem)] ";
|
|
5
|
-
const responsiveSection = `mx-auto ${wideWidth} ${sectionSpacing}`;
|
|
5
|
+
const responsiveSection = `mx-auto ${wideWidth} ${sectionSpacing} w-full`;
|
|
6
6
|
|
|
7
7
|
exports.responsiveSection = responsiveSection;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const sectionSpacing = "px-4 py-10 sm:px-6 md:px-8 lg:px-10 scroll-mt-20";
|
|
2
2
|
const wideWidth = "max-w-6xl min-w-[calc(100vw-22rem)] ";
|
|
3
|
-
const responsiveSection = `mx-auto ${wideWidth} ${sectionSpacing}`;
|
|
3
|
+
const responsiveSection = `mx-auto ${wideWidth} ${sectionSpacing} w-full`;
|
|
4
4
|
|
|
5
5
|
export { responsiveSection };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@windrun-huaiin/third-ui",
|
|
3
|
-
"version": "31.3.
|
|
3
|
+
"version": "31.3.2",
|
|
4
4
|
"description": "Third-party integrated UI components for windrun-huaiin projects",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./clerk": {
|
|
@@ -245,7 +245,7 @@
|
|
|
245
245
|
"zod": "^4.3.6",
|
|
246
246
|
"@windrun-huaiin/base-ui": "^31.0.0",
|
|
247
247
|
"@windrun-huaiin/contracts": "^31.0.0",
|
|
248
|
-
"@windrun-huaiin/lib": "^31.0.
|
|
248
|
+
"@windrun-huaiin/lib": "^31.0.3"
|
|
249
249
|
},
|
|
250
250
|
"peerDependencies": {
|
|
251
251
|
"clsx": "^2.1.1",
|
|
@@ -10,13 +10,17 @@ interface TocFooterProps {
|
|
|
10
10
|
copyButtonComponent?: React.ReactNode;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
function joinUrlPath(baseUrl: string, path: string) {
|
|
14
|
+
return `${baseUrl.replace(/\/+$/, '')}/${path.replace(/^\/+/, '')}`;
|
|
15
|
+
}
|
|
16
|
+
|
|
13
17
|
export function TocFooterWrapper({ lastModified, editPath, githubBaseUrl, copyButtonComponent }: TocFooterProps) {
|
|
14
18
|
const showEdit = githubBaseUrl && editPath;
|
|
15
19
|
return (
|
|
16
20
|
<div className="flex flex-col gap-y-2 items-start m-4">
|
|
17
21
|
<LastUpdatedDate date={lastModified} />
|
|
18
22
|
{copyButtonComponent}
|
|
19
|
-
{showEdit && <EditOnGitHub url={
|
|
23
|
+
{showEdit && <EditOnGitHub url={joinUrlPath(githubBaseUrl, editPath)} />}
|
|
20
24
|
</div>
|
|
21
25
|
);
|
|
22
26
|
}
|
package/src/lib/seo-metadata.ts
CHANGED
|
@@ -10,11 +10,41 @@ export interface CreateLocalizedSiteMetadataOptions {
|
|
|
10
10
|
localePrefixAsNeeded: boolean;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
export interface LocalizedPageUrlOptions extends CreateLocalizedSiteMetadataOptions {
|
|
14
|
+
pathname: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
13
17
|
export type LocalizedSiteMetadata = Pick<
|
|
14
18
|
Metadata,
|
|
15
|
-
'title' | 'description' | 'keywords' | '
|
|
19
|
+
'title' | 'description' | 'keywords' | 'icons' | 'openGraph' | 'twitter'
|
|
20
|
+
>;
|
|
21
|
+
|
|
22
|
+
export type LocalizedPageMetadataOverrides = Pick<
|
|
23
|
+
Metadata,
|
|
24
|
+
| 'title'
|
|
25
|
+
| 'description'
|
|
26
|
+
| 'keywords'
|
|
27
|
+
| 'icons'
|
|
28
|
+
| 'openGraph'
|
|
29
|
+
| 'twitter'
|
|
30
|
+
| 'robots'
|
|
31
|
+
| 'authors'
|
|
32
|
+
| 'creator'
|
|
33
|
+
| 'publisher'
|
|
34
|
+
| 'category'
|
|
16
35
|
>;
|
|
17
36
|
|
|
37
|
+
export interface CreateLocalizedPageMetadataOptions {
|
|
38
|
+
url: LocalizedPageUrlOptions;
|
|
39
|
+
site?: LocalizedSiteMetadata;
|
|
40
|
+
page?: LocalizedPageMetadataOverrides;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface LocalizedNamespaceMetadataOptions {
|
|
44
|
+
url: LocalizedPageUrlOptions;
|
|
45
|
+
namespace: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
18
48
|
const DEFAULT_SITE_ICONS = [
|
|
19
49
|
{ rel: 'icon', type: 'image/png', sizes: '16x16', url: '/favicon-16x16.png' },
|
|
20
50
|
{ rel: 'icon', type: 'image/png', sizes: '32x32', url: '/favicon-32x32.png' },
|
|
@@ -23,25 +53,180 @@ const DEFAULT_SITE_ICONS = [
|
|
|
23
53
|
{ rel: 'android-chrome', sizes: '512x512', url: '/favicon-512x512.png' },
|
|
24
54
|
];
|
|
25
55
|
|
|
56
|
+
function buildAlternateUrls(options: LocalizedPageUrlOptions) {
|
|
57
|
+
const { baseUrl, defaultLocale, locale, localePrefixAsNeeded, locales, pathname } = options;
|
|
58
|
+
const canonicalPath = getAsNeededLocalizedUrl(locale, pathname, localePrefixAsNeeded, defaultLocale);
|
|
59
|
+
const canonical = `${baseUrl}${canonicalPath}`;
|
|
60
|
+
const languages = Object.fromEntries(
|
|
61
|
+
locales.map((siteLocale) => [
|
|
62
|
+
siteLocale,
|
|
63
|
+
`${baseUrl}${getAsNeededLocalizedUrl(siteLocale, pathname, localePrefixAsNeeded, defaultLocale)}`,
|
|
64
|
+
]),
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
canonical,
|
|
69
|
+
languages,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function getOptionalTranslation(
|
|
74
|
+
t: Awaited<ReturnType<typeof getTranslations>>,
|
|
75
|
+
key: string,
|
|
76
|
+
): string | undefined {
|
|
77
|
+
return t.has(key) ? t(key) : undefined;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function getNestedTranslation(
|
|
81
|
+
t: Awaited<ReturnType<typeof getTranslations>>,
|
|
82
|
+
key: string,
|
|
83
|
+
fallback: string | undefined,
|
|
84
|
+
): string | undefined {
|
|
85
|
+
return getOptionalTranslation(t, key) ?? fallback;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function getAbsoluteUrl(baseUrl: string, value: string): string {
|
|
89
|
+
if (/^https?:\/\//i.test(value)) {
|
|
90
|
+
return value;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
|
|
94
|
+
const normalizedPath = value.startsWith('/') ? value : `/${value}`;
|
|
95
|
+
return `${normalizedBaseUrl}${normalizedPath}`;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function getImageUrls(baseUrl: string, value?: string | string[]): { url: string }[] | undefined {
|
|
99
|
+
if (!value) return undefined;
|
|
100
|
+
const urls = Array.isArray(value) ? value : [value];
|
|
101
|
+
const cleaned = urls.map((item) => item.trim()).filter(Boolean);
|
|
102
|
+
return cleaned.length > 0
|
|
103
|
+
? cleaned.map((url) => ({ url: getAbsoluteUrl(baseUrl, url) }))
|
|
104
|
+
: undefined;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function getEnvText(value?: string): string | undefined {
|
|
108
|
+
const trimmed = value?.trim();
|
|
109
|
+
return trimmed ? trimmed : undefined;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export async function resolveMetadataOverrides(options: {
|
|
113
|
+
locale: string;
|
|
114
|
+
namespace: string;
|
|
115
|
+
}): Promise<LocalizedPageMetadataOverrides> {
|
|
116
|
+
const { locale, namespace } = options;
|
|
117
|
+
const t = await getTranslations({ locale, namespace });
|
|
118
|
+
const ogType = getEnvText(process.env.NEXT_PUBLIC_OG_TYPE);
|
|
119
|
+
const xSiteName = getEnvText(process.env.NEXT_PUBLIC_X_SITE_NAME);
|
|
120
|
+
const baseUrl = getEnvText(process.env.NEXT_PUBLIC_BASE_URL) ?? '';
|
|
121
|
+
const title = getOptionalTranslation(t, 'title');
|
|
122
|
+
const description = getOptionalTranslation(t, 'description');
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
title,
|
|
126
|
+
description,
|
|
127
|
+
keywords: getOptionalTranslation(t, 'keywords'),
|
|
128
|
+
openGraph: {
|
|
129
|
+
...(ogType ? { type: ogType as any } : {}),
|
|
130
|
+
title: getNestedTranslation(t, 'openGraph.title', title),
|
|
131
|
+
description: getNestedTranslation(t, 'openGraph.description', description),
|
|
132
|
+
images: getImageUrls(
|
|
133
|
+
baseUrl,
|
|
134
|
+
getOptionalTranslation(t, 'openGraph.image') ?? getOptionalTranslation(t, 'openGraph.images'),
|
|
135
|
+
),
|
|
136
|
+
},
|
|
137
|
+
twitter: {
|
|
138
|
+
...(xSiteName ? { site: xSiteName } : {}),
|
|
139
|
+
title: getNestedTranslation(t, 'twitter.title', title),
|
|
140
|
+
description: getNestedTranslation(t, 'twitter.description', description),
|
|
141
|
+
images: getImageUrls(
|
|
142
|
+
baseUrl,
|
|
143
|
+
getOptionalTranslation(t, 'twitter.image') ?? getOptionalTranslation(t, 'twitter.images'),
|
|
144
|
+
),
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
26
149
|
export async function createLocalizedSiteMetadata(
|
|
27
150
|
options: CreateLocalizedSiteMetadataOptions,
|
|
28
151
|
): Promise<LocalizedSiteMetadata> {
|
|
29
|
-
const {
|
|
152
|
+
const { locale } = options;
|
|
30
153
|
const t = await getTranslations({ locale, namespace: 'home' });
|
|
154
|
+
const ogType = getEnvText(process.env.NEXT_PUBLIC_OG_TYPE);
|
|
155
|
+
const xSiteName = getEnvText(process.env.NEXT_PUBLIC_X_SITE_NAME);
|
|
156
|
+
const baseUrl = getEnvText(process.env.NEXT_PUBLIC_BASE_URL) ?? '';
|
|
157
|
+
const title = t('webTitle');
|
|
158
|
+
const description = t('webDescription');
|
|
159
|
+
const ogTitle = getNestedTranslation(t, 'openGraph.title', title);
|
|
160
|
+
const ogDescription = getNestedTranslation(t, 'openGraph.description', description);
|
|
161
|
+
const twitterTitle = getNestedTranslation(t, 'twitter.title', title);
|
|
162
|
+
const twitterDescription = getNestedTranslation(t, 'twitter.description', description);
|
|
31
163
|
|
|
32
164
|
return {
|
|
33
|
-
title
|
|
34
|
-
description
|
|
165
|
+
title,
|
|
166
|
+
description,
|
|
35
167
|
keywords: t('keywords'),
|
|
36
|
-
alternates: {
|
|
37
|
-
canonical: `${baseUrl}${getAsNeededLocalizedUrl(locale, '/', localePrefixAsNeeded, defaultLocale)}`,
|
|
38
|
-
languages: Object.fromEntries(
|
|
39
|
-
locales.map((siteLocale) => [
|
|
40
|
-
siteLocale,
|
|
41
|
-
`${baseUrl}${getAsNeededLocalizedUrl(siteLocale, '/', localePrefixAsNeeded, defaultLocale)}`,
|
|
42
|
-
]),
|
|
43
|
-
),
|
|
44
|
-
},
|
|
45
168
|
icons: DEFAULT_SITE_ICONS,
|
|
169
|
+
openGraph: {
|
|
170
|
+
...(ogType ? { type: ogType as any } : {}),
|
|
171
|
+
title: ogTitle,
|
|
172
|
+
description: ogDescription,
|
|
173
|
+
images: getImageUrls(baseUrl, getOptionalTranslation(t, 'openGraph.image')),
|
|
174
|
+
},
|
|
175
|
+
twitter: {
|
|
176
|
+
...(xSiteName ? { site: xSiteName } : {}),
|
|
177
|
+
title: twitterTitle,
|
|
178
|
+
description: twitterDescription,
|
|
179
|
+
images: getImageUrls(baseUrl, getOptionalTranslation(t, 'twitter.image')),
|
|
180
|
+
},
|
|
46
181
|
};
|
|
47
182
|
}
|
|
183
|
+
|
|
184
|
+
export function createLocalizedPageMetadata(
|
|
185
|
+
options: CreateLocalizedPageMetadataOptions,
|
|
186
|
+
): Metadata {
|
|
187
|
+
const { page, site, url } = options;
|
|
188
|
+
const { baseUrl } = url;
|
|
189
|
+
const alternates = buildAlternateUrls(url);
|
|
190
|
+
const openGraph = {
|
|
191
|
+
...site?.openGraph,
|
|
192
|
+
...page?.openGraph,
|
|
193
|
+
url: alternates.canonical,
|
|
194
|
+
} as Metadata['openGraph'];
|
|
195
|
+
const twitter = {
|
|
196
|
+
...site?.twitter,
|
|
197
|
+
...page?.twitter,
|
|
198
|
+
} as Metadata['twitter'];
|
|
199
|
+
|
|
200
|
+
return {
|
|
201
|
+
metadataBase: new URL(baseUrl),
|
|
202
|
+
title: page?.title ?? site?.title,
|
|
203
|
+
description: page?.description ?? site?.description,
|
|
204
|
+
keywords: page?.keywords ?? site?.keywords,
|
|
205
|
+
icons: page?.icons ?? site?.icons,
|
|
206
|
+
openGraph,
|
|
207
|
+
twitter,
|
|
208
|
+
robots: page?.robots,
|
|
209
|
+
authors: page?.authors,
|
|
210
|
+
creator: page?.creator,
|
|
211
|
+
publisher: page?.publisher,
|
|
212
|
+
category: page?.category,
|
|
213
|
+
alternates,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export async function createLocalizedMetadata(
|
|
218
|
+
options: LocalizedNamespaceMetadataOptions,
|
|
219
|
+
): Promise<Metadata> {
|
|
220
|
+
const { namespace, url } = options;
|
|
221
|
+
const site = await createLocalizedSiteMetadata(url);
|
|
222
|
+
const page = await resolveMetadataOverrides({
|
|
223
|
+
locale: url.locale,
|
|
224
|
+
namespace,
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
return createLocalizedPageMetadata({
|
|
228
|
+
url,
|
|
229
|
+
site,
|
|
230
|
+
page,
|
|
231
|
+
});
|
|
232
|
+
}
|
package/src/main/cta.tsx
CHANGED
|
@@ -72,11 +72,10 @@ export async function CTA({
|
|
|
72
72
|
<h2 className="mb-6 text-3xl font-bold text-neutral-950 md:text-4xl dark:text-neutral-50">
|
|
73
73
|
{data.title} <span className={themeIconColor}>{data.eyesOn}</span>?
|
|
74
74
|
</h2>
|
|
75
|
-
<
|
|
76
|
-
{data.description1}
|
|
77
|
-
<
|
|
78
|
-
|
|
79
|
-
</p>
|
|
75
|
+
<div className="mx-auto mb-8 space-y-2 max-w-4xl text-base text-neutral-700 sm:text-xl dark:text-neutral-300">
|
|
76
|
+
<p>{data.description1}</p>
|
|
77
|
+
<p className={cn(themeIconColor, "text-xl sm:text-2xl")}>{data.description2}</p>
|
|
78
|
+
</div>
|
|
80
79
|
<GradientButton
|
|
81
80
|
title={data.button}
|
|
82
81
|
href={data.url}
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
const sectionSpacing = "px-4 py-10 sm:px-6 md:px-8 lg:px-10 scroll-mt-20";
|
|
3
3
|
const wideWidth = "max-w-6xl min-w-[calc(100vw-22rem)] ";
|
|
4
4
|
|
|
5
|
-
export const responsiveSection = `mx-auto ${wideWidth} ${sectionSpacing}`;
|
|
5
|
+
export const responsiveSection = `mx-auto ${wideWidth} ${sectionSpacing} w-full`;
|