Skip to content

Commit 254de27

Browse files
committed
chore: more cleanup and improvements
1 parent 5b3014a commit 254de27

File tree

6 files changed

+175
-154
lines changed

6 files changed

+175
-154
lines changed

apps/site/app/[locale]/[...path]/page.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
import { notFound } from 'next/navigation';
1111
import type { FC } from 'react';
1212

13-
import * as basePage from '#site/app/[locale]/page';
1413
import { ENABLE_STATIC_EXPORT } from '#site/next.constants.mjs';
1514
import { ENABLE_STATIC_EXPORT_LOCALE } from '#site/next.constants.mjs';
1615
import { dynamicRouter } from '#site/next.dynamic.mjs';
16+
import * as basePage from '#site/next.dynamic.page.mjs';
1717
import { availableLocaleCodes, defaultLocale } from '#site/next.locales.mjs';
1818

1919
type DynamicStaticPaths = { path: Array<string>; locale: string };
@@ -64,10 +64,10 @@ const getPage: FC<DynamicParams> = async props => {
6464
const [locale, pathname] = await basePage.getLocaleAndPath(props);
6565

6666
// Gets the Markdown content and context
67-
const [content, context] = await basePage.getMarkdownContext(
67+
const [content, context] = await basePage.getMarkdownContext({
6868
locale,
69-
pathname
70-
);
69+
pathname,
70+
});
7171

7272
// If we have a filename and layout then we have a page
7373
if (context.filename && context.frontmatter.layout) {

apps/site/app/[locale]/blog/[...path]/page.tsx

Lines changed: 6 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,14 @@
1-
/**
2-
* This file extends on the `page.tsx` file, which is the default file that is used to render
3-
* the entry points for each locale and then also reused within the [...path] route to render the
4-
* and contains all logic for rendering our dynamic and static routes within the Node.js Website.
5-
*
6-
* Note: that each `page.tsx` should have its own `generateStaticParams` to prevent clash of
7-
* dynamic params, which will lead on static export errors and other sort of issues.
8-
*/
9-
101
import { notFound } from 'next/navigation';
112
import type { FC } from 'react';
123

13-
import * as basePage from '#site/app/[locale]/page';
14-
import { provideBlogPosts } from '#site/next-data/providers/blogData';
154
import { ENABLE_STATIC_EXPORT } from '#site/next.constants.mjs';
16-
import { blogData } from '#site/next.json.mjs';
5+
import { BLOG_DYNAMIC_ROUTES } from '#site/next.dynamic.constants.mjs';
6+
import * as basePage from '#site/next.dynamic.page.mjs';
177
import { defaultLocale } from '#site/next.locales.mjs';
188

199
type DynamicStaticPaths = { path: Array<string>; locale: string };
2010
type DynamicParams = { params: Promise<DynamicStaticPaths> };
2111

22-
/**
23-
* This constant is used to create static routes on-the-fly that do not have a file-system
24-
* counterpart route. This is useful for providing routes with matching Layout Names
25-
* but that do not have Markdown content and a matching file for the route
26-
*
27-
* @type {Array<string>} A Map of pathname and Layout Name
28-
*/
29-
export const BLOG_DYNAMIC_ROUTES = [
30-
// Provides Routes for all Blog Categories
31-
...blogData.categories,
32-
// Provides Routes for all Blog Categories w/ Pagination
33-
...blogData.categories
34-
// retrieves the amount of pages for each blog category
35-
.map(c => [c, provideBlogPosts(c).pagination.pages])
36-
// creates a numeric array for each page and define a pathname for
37-
// each page for a category (i.e. blog/all/page/1)
38-
.map(([c, t]) => [...Array(t).keys()].map(p => `${c}/page/${p + 1}`))
39-
// flattens the array since we have a .map inside another .map
40-
.flat(),
41-
];
42-
4312
// This is the default Viewport Metadata
4413
// @see https://nextjs.org/docs/app/api-reference/functions/generate-viewport#generateviewport-function
4514
export const generateViewport = basePage.generateViewport;
@@ -78,10 +47,10 @@ const getPage: FC<DynamicParams> = async props => {
7847

7948
// Gets the Markdown content and context for Blog pages
8049
// otherwise this is likely a blog-category or a blog post
81-
const [content, context] = await basePage.getMarkdownContext(
82-
locale,
83-
`blog/${pathname}`
84-
);
50+
const [content, context] = await basePage.getMarkdownContext({
51+
locale: locale,
52+
pathname: `blog/${pathname}`,
53+
});
8554

8655
// If this isn't a valid dynamic route for blog post or there's no mardown file
8756
// for this, then we fail as not found as there's nothing we can do.

apps/site/app/[locale]/page.tsx

Lines changed: 21 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,31 @@
1-
/**
2-
* This file contains the logic for rendering our dynamic and static routes within the Node.js Website
3-
* this page route template is used to render the entry points for each locale and then also reused within
4-
* the [...path] route to render the individual pages under each locale of the Website.
5-
*
6-
* Note: that each `page.tsx` should have its own `generateStaticParams` to prevent clash of
7-
* dynamic params, which will lead on static export errors and other sort of issues.
8-
*/
1+
import { notFound } from 'next/navigation';
2+
import type { FC } from 'react';
93

10-
import { notFound, redirect } from 'next/navigation';
11-
import { setRequestLocale } from 'next-intl/server';
12-
import type { FC, ReactNode } from 'react';
13-
14-
import { setClientContext } from '#site/client-context';
15-
import WithLayout from '#site/components/withLayout';
164
import { ENABLE_STATIC_EXPORT } from '#site/next.constants.mjs';
175
import { ENABLE_STATIC_EXPORT_LOCALE } from '#site/next.constants.mjs';
18-
import { PAGE_VIEWPORT } from '#site/next.dynamic.constants.mjs';
19-
import { dynamicRouter } from '#site/next.dynamic.mjs';
20-
import { allLocaleCodes, availableLocaleCodes } from '#site/next.locales.mjs';
6+
import * as basePage from '#site/next.dynamic.page.mjs';
7+
import { availableLocaleCodes } from '#site/next.locales.mjs';
218
import { defaultLocale } from '#site/next.locales.mjs';
22-
import { MatterProvider } from '#site/providers/matterProvider';
23-
import type { Layouts } from '#site/types/layouts';
24-
import type { ClientSharedServerContext } from '#site/types/server';
259

2610
type DynamicStaticPaths = { path: Array<string>; locale: string };
2711
type DynamicParams = { params: Promise<DynamicStaticPaths> };
2812

29-
type DynamicPageRender = {
30-
content: ReactNode;
31-
layout: Layouts;
32-
context: Partial<ClientSharedServerContext>;
33-
};
34-
3513
// This is the default Viewport Metadata
3614
// @see https://nextjs.org/docs/app/api-reference/functions/generate-viewport#generateviewport-function
37-
export const generateViewport = () => ({ ...PAGE_VIEWPORT });
15+
export const generateViewport = basePage.generateViewport;
3816

3917
// This generates each page's HTML Metadata
4018
// @see https://nextjs.org/docs/app/api-reference/functions/generate-metadata
41-
export const generateMetadata = async (props: DynamicParams) => {
42-
const { path = [], locale = defaultLocale.code } = await props.params;
43-
44-
const pathname = dynamicRouter.getPathname(path);
45-
46-
return dynamicRouter.getPageMetadata(locale, pathname);
47-
};
19+
export const generateMetadata = basePage.generateMetadata;
4820

49-
// Generates all possible static paths based on the locales and environment configuration
50-
// - Returns an empty array if static export is disabled (`ENABLE_STATIC_EXPORT` is false)
51-
// - If `ENABLE_STATIC_EXPORT_LOCALE` is true, generates paths for all available locales
52-
// - Otherwise, generates paths only for the default locale
53-
// @see https://nextjs.org/docs/app/api-reference/functions/generate-static-params
21+
/**
22+
* Generates all possible static paths based on the locales and environment configuration
23+
* - Returns an empty array if static export is disabled (`ENABLE_STATIC_EXPORT` is false)
24+
* - If `ENABLE_STATIC_EXPORT_LOCALE` is true, generates paths for all available locales
25+
* - Otherwise, generates paths only for the default locale
26+
*
27+
* @see https://nextjs.org/docs/app/api-reference/functions/generate-static-params
28+
*/
5429
export const generateStaticParams = async () => {
5530
// Return an empty array if static export is disabled
5631
if (!ENABLE_STATIC_EXPORT) {
@@ -64,95 +39,29 @@ export const generateStaticParams = async () => {
6439

6540
const routes = await Promise.all(
6641
// Gets all mapped routes to the Next.js Routing Engine by Locale
67-
locales.map((locale: string) => ({ locale }))
42+
locales.map(locale => ({ locale }))
6843
);
6944

7045
return routes.flat().sort();
7146
};
7247

73-
// This method is used for retrieving the current locale and pathname from the request
74-
export const getLocaleAndPath = async (props: DynamicParams) => {
75-
const { path = [], locale = defaultLocale.code } = await props.params;
76-
77-
if (!availableLocaleCodes.includes(locale)) {
78-
// Forces the current locale to be the Default Locale
79-
setRequestLocale(defaultLocale.code);
80-
81-
if (!allLocaleCodes.includes(locale)) {
82-
// when the locale is not listed in the locales, return NotFound
83-
return notFound();
84-
}
85-
86-
// Redirect to the default locale path
87-
const pathname = dynamicRouter.getPathname(path);
88-
89-
return redirect(`/${defaultLocale.code}/${pathname}`);
90-
}
91-
92-
// Configures the current Locale to be the given Locale of the Request
93-
setRequestLocale(locale);
94-
95-
// Gets the current full pathname for a given path
96-
return [locale, dynamicRouter.getPathname(path)] as const;
97-
};
98-
99-
// This method is used for retrieving the Markdown content and context
100-
export const getMarkdownContext = async (locale: string, pathname: string) => {
101-
// We retrieve the source of the Markdown file by doing an educated guess
102-
// of what possible files could be the source of the page, since the extension
103-
// context is lost from `getStaticProps` as a limitation of Next.js itself
104-
const { source, filename } = await dynamicRouter.getMarkdownFile(
105-
locale,
106-
pathname
107-
);
108-
109-
// This parses the source Markdown content and returns a React Component and
110-
// relevant context from the Markdown File
111-
const { content, frontmatter, headings, readingTime } =
112-
await dynamicRouter.getMDXContent(source, filename);
113-
114-
// Metadata and shared Context to be available through the lifecycle of the page
115-
const context = {
116-
frontmatter: frontmatter,
117-
headings: headings,
118-
pathname: `/${pathname}`,
119-
readingTime: readingTime,
120-
filename: filename,
121-
};
122-
123-
return [content, context] as const;
124-
};
125-
126-
// This method is used for rendering the actual page
127-
export const renderPage: FC<DynamicPageRender> = props => {
128-
// Defines a shared Server Context for the Client-Side
129-
// That is shared for all pages under the dynamic router
130-
setClientContext(props.context);
131-
132-
// The Matter Provider allows Client-Side injection of the data
133-
// to a shared React Client Provider even though the page is rendered
134-
// within a server-side context
135-
return (
136-
<MatterProvider {...props.context}>
137-
<WithLayout layout={props.layout}>{props.content}</WithLayout>
138-
</MatterProvider>
139-
);
140-
};
141-
14248
// This method parses the current pathname and does any sort of modifications needed on the route
14349
// then it proceeds to retrieve the Markdown file and parse the MDX Content into a React Component
14450
// finally it returns (if the locale and route are valid) the React Component with the relevant context
14551
// and attached context providers for rendering the current page
14652
const getPage: FC<DynamicParams> = async props => {
14753
// Gets the current full pathname for a given path
148-
const [locale, pathname] = await getLocaleAndPath(props);
54+
const [locale, pathname] = await basePage.getLocaleAndPath(props);
14955

15056
// Gets the Markdown content and context
151-
const [content, context] = await getMarkdownContext(locale, pathname);
57+
const [content, context] = await basePage.getMarkdownContext({
58+
locale,
59+
pathname,
60+
});
15261

15362
// If we have a filename and layout then we have a page
15463
if (context.filename && context.frontmatter.layout) {
155-
return renderPage({
64+
return basePage.renderPage({
15665
content: content,
15766
layout: context.frontmatter.layout,
15867
context: context,

apps/site/app/sitemap.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import type { MetadataRoute } from 'next';
22

3-
import { BLOG_DYNAMIC_ROUTES } from '#site/app/[locale]/blog/[...path]/page';
43
import { BASE_PATH } from '#site/next.constants.mjs';
54
import { BASE_URL } from '#site/next.constants.mjs';
65
import { EXTERNAL_LINKS_SITEMAP } from '#site/next.constants.mjs';
6+
import { BLOG_DYNAMIC_ROUTES } from '#site/next.dynamic.constants.mjs';
77
import { dynamicRouter } from '#site/next.dynamic.mjs';
88
import { availableLocaleCodes, defaultLocale } from '#site/next.locales.mjs';
99

apps/site/next.dynamic.constants.mjs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,32 @@
11
'use strict';
22

3+
import { provideBlogPosts } from '#site/next-data/providers/blogData';
4+
import { blogData } from '#site/next.json.mjs';
5+
36
import { BASE_PATH, BASE_URL } from './next.constants.mjs';
47
import { siteConfig } from './next.json.mjs';
58

9+
/**
10+
* This constant is used to create static routes on-the-fly that do not have a file-system
11+
* counterpart route. This is useful for providing routes with matching Layout Names
12+
* but that do not have Markdown content and a matching file for the route
13+
*
14+
* @type {Array<string>} A Map of pathname and Layout Name
15+
*/
16+
export const BLOG_DYNAMIC_ROUTES = [
17+
// Provides Routes for all Blog Categories
18+
...blogData.categories,
19+
// Provides Routes for all Blog Categories w/ Pagination
20+
...blogData.categories
21+
// retrieves the amount of pages for each blog category
22+
.map(c => [c, provideBlogPosts(c).pagination.pages])
23+
// creates a numeric array for each page and define a pathname for
24+
// each page for a category (i.e. blog/all/page/1)
25+
.map(([c, t]) => [...Array(t).keys()].map(p => `${c}/page/${p + 1}`))
26+
// flattens the array since we have a .map inside another .map
27+
.flat(),
28+
];
29+
630
/**
731
* This is the default Next.js Page Metadata for all pages
832
*

0 commit comments

Comments
 (0)