-
Notifications
You must be signed in to change notification settings - Fork 6.5k
Expand file tree
/
Copy pathnext.dynamic.page.mjs
More file actions
134 lines (115 loc) · 4.72 KB
/
next.dynamic.page.mjs
File metadata and controls
134 lines (115 loc) · 4.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import { sep } from 'node:path';
import { notFound, redirect } from 'next/navigation';
import { setRequestLocale } from 'next-intl/server';
import { setClientContext } from '#site/client-context';
import WithLayout from '#site/components/withLayout';
import { PAGE_VIEWPORT } from '#site/next.dynamic.constants.mjs';
import { dynamicRouter } from '#site/next.dynamic.mjs';
import { allLocaleCodes, availableLocaleCodes } from '#site/next.locales.mjs';
import { defaultLocale } from '#site/next.locales.mjs';
import { MatterProvider } from '#site/providers/matterProvider';
/**
* This is the default Viewport Metadata
*
* @see https://nextjs.org/docs/app/api-reference/functions/generate-viewport#generateviewport-function
*
* @returns {import('next').Viewport} the default viewport metadata
*/
export const generateViewport = () => ({ ...PAGE_VIEWPORT });
/**
* This generates each page's HTML Metadata
*
* @see https://nextjs.org/docs/app/api-reference/functions/generate-metadata
*
* @param {{ params: Promise<{ path: Array<string>; locale: string }> }} props
* @returns {Promise<import('next').Metadata>} the metadata for the page
*/
export const generateMetadata = async props => {
const { path = [], locale = defaultLocale.code } = await props.params;
const pathname = dynamicRouter.getPathname(path);
return dynamicRouter.getPageMetadata(locale, pathname);
};
/**
* This generates each blog's HTML Metadata
*
* @see https://nextjs.org/docs/app/api-reference/functions/generate-metadata
*
* @param {{ params: Promise<{ path: Array<string>; locale: string }> }} props
* @returns {Promise<import('next').Metadata>} the metadata for the page
*/
export const generateBlogMetadata = async props => {
const { path = [], locale = defaultLocale.code } = await props.params;
const pathname = dynamicRouter.getPathname(path);
return dynamicRouter.getPageMetadata(locale, `blog${sep}${pathname}`);
};
/**
* This method is used for retrieving the current locale and pathname from the request
*
* @param {string|Array<string>} path
* @param {string} locale
* @returns {[string, string]} the locale and pathname for the request
*/
export const getLocaleAndPath = (path = [], locale = defaultLocale.code) => {
if (!availableLocaleCodes.includes(locale)) {
// Forces the current locale to be the Default Locale
setRequestLocale(defaultLocale.code);
if (!allLocaleCodes.includes(locale)) {
// when the locale is not listed in the locales, return NotFound
return notFound();
}
// Redirect to the default locale path
const pathname = dynamicRouter.getPathname(path);
return redirect(`/${defaultLocale.code}/${pathname}`);
}
// Configures the current Locale to be the given Locale of the Request
setRequestLocale(locale);
// Gets the current full pathname for a given path
return [locale, dynamicRouter.getPathname(path)];
};
/**
* This method is used for retrieving the Markdown content and context
*
* @param {{ locale: string; pathname: string }} props
* @returns {Promise<[import('react').ReactNode, import('#site/types/server').ClientSharedServerContext]>}
*/
export const getMarkdownContext = async props => {
// We retrieve the source of the Markdown file by doing an educated guess
// of what possible files could be the source of the page, since the extension
// context is lost from `getStaticProps` as a limitation of Next.js itself
const { source, filename } = await dynamicRouter.getMarkdownFile(
props.locale,
props.pathname
);
// This parses the source Markdown content and returns a React Component and
// relevant context from the Markdown File
const { content, frontmatter, headings, readingTime } =
await dynamicRouter.getMDXContent(source, filename);
// Metadata and shared Context to be available through the lifecycle of the page
const context = {
frontmatter,
headings,
pathname: `/${props.pathname}`,
readingTime,
filename,
};
return [content, context];
};
/**
* This method is used for rendering the actual page
*
* @param {{ content: import('react').ReactNode; layout: import('#site/types/layouts').Layouts; context: Partial<import('#site/types/server').ClientSharedServerContext>; }} props
* @returns {import('react').ReactElement}
*/
export const renderPage = props => {
// Defines a shared Server Context for the Client-Side
// That is shared for all pages under the dynamic router
setClientContext(props.context);
// The Matter Provider allows Client-Side injection of the data
// to a shared React Client Provider even though the page is rendered
// within a server-side context
return (
<MatterProvider {...props.context}>
<WithLayout layout={props.layout}>{props.content}</WithLayout>
</MatterProvider>
);
};