Skip to content

Commit afc2f86

Browse files
committed
getting home page working
1 parent 7e62576 commit afc2f86

File tree

14 files changed

+461
-470
lines changed

14 files changed

+461
-470
lines changed

next.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ const nextConfig = {
1313
reactCompiler: true,
1414
},
1515
env: {},
16+
serverExternalPackages: [
17+
'@babel/core',
18+
'@babel/plugin-transform-modules-commonjs',
19+
],
1620
webpack: (config, {dev, isServer, ...options}) => {
1721
if (process.env.ANALYZE) {
1822
const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer');
Lines changed: 92 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,24 @@
1-
/*
2-
* Copyright (c) Facebook, Inc. and its affiliates.
3-
*/
4-
5-
import {Fragment, useMemo} from 'react';
6-
import {useRouter} from 'next/router';
1+
// src/app/[[...markdownPath]]/page.js
2+
import {Fragment} from 'react';
3+
import fs from 'fs/promises';
4+
import path from 'path';
75
import {Page} from 'components/Layout/Page';
8-
import sidebarHome from '../sidebarHome.json';
9-
import sidebarLearn from '../sidebarLearn.json';
10-
import sidebarReference from '../sidebarReference.json';
11-
import sidebarCommunity from '../sidebarCommunity.json';
12-
import sidebarBlog from '../sidebarBlog.json';
6+
import sidebarHome from '../../sidebarHome.json';
7+
import sidebarLearn from '../../sidebarLearn.json';
8+
import sidebarReference from '../../sidebarReference.json';
9+
import sidebarCommunity from '../../sidebarCommunity.json';
10+
import sidebarBlog from '../../sidebarBlog.json';
1311
import {MDXComponents} from 'components/MDX/MDXComponents';
1412
import compileMDX from 'utils/compileMDX';
15-
import {generateRssFeed} from '../utils/rss';
16-
17-
export default function Layout({content, toc, meta, languages}) {
18-
const parsedContent = useMemo(
19-
() => JSON.parse(content, reviveNodeOnClient),
20-
[content]
21-
);
22-
const parsedToc = useMemo(() => JSON.parse(toc, reviveNodeOnClient), [toc]);
23-
const section = useActiveSection();
24-
let routeTree;
25-
switch (section) {
26-
case 'home':
27-
case 'unknown':
28-
routeTree = sidebarHome;
29-
break;
30-
case 'learn':
31-
routeTree = sidebarLearn;
32-
break;
33-
case 'reference':
34-
routeTree = sidebarReference;
35-
break;
36-
case 'community':
37-
routeTree = sidebarCommunity;
38-
break;
39-
case 'blog':
40-
routeTree = sidebarBlog;
41-
break;
42-
}
43-
return (
44-
<Page
45-
toc={parsedToc}
46-
routeTree={routeTree}
47-
meta={meta}
48-
section={section}
49-
languages={languages}>
50-
{parsedContent}
51-
</Page>
52-
);
53-
}
54-
55-
function useActiveSection() {
56-
const {asPath} = useRouter();
57-
const cleanedPath = asPath.split(/[\?\#]/)[0];
58-
if (cleanedPath === '/') {
59-
return 'home';
60-
} else if (cleanedPath.startsWith('/reference')) {
61-
return 'reference';
62-
} else if (asPath.startsWith('/learn')) {
63-
return 'learn';
64-
} else if (asPath.startsWith('/community')) {
65-
return 'community';
66-
} else if (asPath.startsWith('/blog')) {
67-
return 'blog';
68-
} else {
69-
return 'unknown';
70-
}
71-
}
13+
import {generateRssFeed} from '../../utils/rss';
7214

7315
// Deserialize a client React tree from JSON.
7416
function reviveNodeOnClient(parentPropertyName, val) {
7517
if (Array.isArray(val) && val[0] == '$r') {
76-
// Assume it's a React element.
7718
let Type = val[1];
7819
let key = val[2];
7920
if (key == null) {
80-
key = parentPropertyName; // Index within a parent.
21+
key = parentPropertyName;
8122
}
8223
let props = val[3];
8324
if (Type === 'wrapper') {
@@ -97,62 +38,77 @@ function reviveNodeOnClient(parentPropertyName, val) {
9738
}
9839
}
9940

100-
// Put MDX output into JSON for client.
101-
export async function getStaticProps(context) {
102-
generateRssFeed();
103-
const fs = require('fs');
104-
const rootDir = process.cwd() + '/src/content/';
41+
function getActiveSection(pathname) {
42+
if (pathname === '/') {
43+
return 'home';
44+
} else if (pathname.startsWith('/reference')) {
45+
return 'reference';
46+
} else if (pathname.startsWith('/learn')) {
47+
return 'learn';
48+
} else if (pathname.startsWith('/community')) {
49+
return 'community';
50+
} else if (pathname.startsWith('/blog')) {
51+
return 'blog';
52+
} else {
53+
return 'unknown';
54+
}
55+
}
56+
57+
async function getRouteTree(section) {
58+
switch (section) {
59+
case 'home':
60+
case 'unknown':
61+
return sidebarHome;
62+
case 'learn':
63+
return sidebarLearn;
64+
case 'reference':
65+
return sidebarReference;
66+
case 'community':
67+
return sidebarCommunity;
68+
case 'blog':
69+
return sidebarBlog;
70+
}
71+
}
10572

106-
// Read MDX from the file.
107-
let path = (context.params.markdownPath || []).join('/') || 'index';
73+
// This replaces getStaticProps
74+
async function getPageContent(markdownPath) {
75+
const rootDir = path.join(process.cwd(), 'src/content');
76+
let mdxPath = markdownPath?.join('/') || 'index';
10877
let mdx;
78+
10979
try {
110-
mdx = fs.readFileSync(rootDir + path + '.md', 'utf8');
80+
mdx = await fs.readFile(path.join(rootDir, mdxPath + '.md'), 'utf8');
11181
} catch {
112-
mdx = fs.readFileSync(rootDir + path + '/index.md', 'utf8');
82+
mdx = await fs.readFile(path.join(rootDir, mdxPath, 'index.md'), 'utf8');
11383
}
11484

115-
const {toc, content, meta, languages} = await compileMDX(mdx, path, {});
116-
return {
117-
props: {
118-
toc,
119-
content,
120-
meta,
121-
languages,
122-
},
123-
};
85+
// Generate RSS feed during build time
86+
if (process.env.NODE_ENV === 'production') {
87+
await generateRssFeed();
88+
}
89+
90+
return await compileMDX(mdx, mdxPath, {});
12491
}
12592

126-
// Collect all MDX files for static generation.
127-
export async function getStaticPaths() {
128-
const {promisify} = require('util');
129-
const {resolve} = require('path');
130-
const fs = require('fs');
131-
const readdir = promisify(fs.readdir);
132-
const stat = promisify(fs.stat);
133-
const rootDir = process.cwd() + '/src/content';
93+
// This replaces getStaticPaths
94+
export async function generateStaticParams() {
95+
const rootDir = path.join(process.cwd(), 'src/content');
13496

135-
// Find all MD files recursively.
13697
async function getFiles(dir) {
137-
const subdirs = await readdir(dir);
98+
const entries = await fs.readdir(dir, {withFileTypes: true});
13899
const files = await Promise.all(
139-
subdirs.map(async (subdir) => {
140-
const res = resolve(dir, subdir);
141-
return (await stat(res)).isDirectory()
100+
entries.map(async (entry) => {
101+
const res = path.resolve(dir, entry.name);
102+
return entry.isDirectory()
142103
? getFiles(res)
143104
: res.slice(rootDir.length + 1);
144105
})
145106
);
146-
return (
147-
files
148-
.flat()
149-
// ignores `errors/*.md`, they will be handled by `pages/errors/[errorCode].tsx`
150-
.filter((file) => file.endsWith('.md') && !file.startsWith('errors/'))
151-
);
107+
return files
108+
.flat()
109+
.filter((file) => file.endsWith('.md') && !file.startsWith('errors/'));
152110
}
153111

154-
// 'foo/bar/baz.md' -> ['foo', 'bar', 'baz']
155-
// 'foo/bar/qux/index.md' -> ['foo', 'bar', 'qux']
156112
function getSegments(file) {
157113
let segments = file.slice(0, -3).replace(/\\/g, '/').split('/');
158114
if (segments[segments.length - 1] === 'index') {
@@ -163,17 +119,33 @@ export async function getStaticPaths() {
163119

164120
const files = await getFiles(rootDir);
165121

166-
const paths = files.map((file) => ({
167-
params: {
168-
markdownPath: getSegments(file),
169-
// ^^^ CAREFUL HERE.
170-
// If you rename markdownPath, update patches/next-remote-watch.patch too.
171-
// Otherwise you'll break Fast Refresh for all MD files.
172-
},
122+
return files.map((file) => ({
123+
markdownPath: getSegments(file),
173124
}));
125+
}
126+
127+
export default async function WrapperPage({params}) {
128+
const {markdownPath} = params;
129+
const {content, toc, meta, languages} = await getPageContent(markdownPath);
130+
131+
const pathname = '/' + (markdownPath?.join('/') || '');
132+
const section = getActiveSection(pathname);
133+
const routeTree = await getRouteTree(section);
174134

175-
return {
176-
paths: paths,
177-
fallback: false,
178-
};
135+
const parsedContent = JSON.parse(content, reviveNodeOnClient);
136+
const parsedToc = JSON.parse(toc, reviveNodeOnClient);
137+
138+
return (
139+
<Page
140+
toc={parsedToc}
141+
routeTree={routeTree}
142+
meta={meta}
143+
section={section}
144+
languages={languages}>
145+
{parsedContent}
146+
</Page>
147+
);
179148
}
149+
150+
// Configure dynamic segments to be statically generated
151+
export const dynamicParams = false;

0 commit comments

Comments
 (0)