Skip to content

Commit 49aac84

Browse files
committed
redirect about to root
1 parent 23682e4 commit 49aac84

File tree

4 files changed

+175
-8
lines changed

4 files changed

+175
-8
lines changed

components/BlogPage/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const BlogPage = ({
1818
{categories.map(category => (
1919
<Link
2020
key={category}
21-
href={category === currentCategory ? '/blog' : `/blog/${category}`}
21+
href={category === currentCategory ? '/blog' : `/blog/category/${category}`}
2222
>
2323
<a className={category === currentCategory ? 'active' : ''}>
2424
{category}

next.config.js

+9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@ const withPlugins = require('next-compose-plugins');
22
const optimizedImages = require('next-optimized-images');
33

44
const nextConfig = {
5+
async redirects() {
6+
return [
7+
{
8+
source: '/about',
9+
destination: '/',
10+
permanent: false
11+
}
12+
];
13+
},
514
swcMinify: true,
615
images: {
716
disableStaticImages: true

pages/blog/[postname].js

+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/* eslint-disable global-require */
2+
/* eslint-disable import/no-dynamic-require */
3+
import PropTypes from 'prop-types';
4+
import matter from 'gray-matter';
5+
import ReactMarkdown from 'react-markdown';
6+
import remarkGfm from 'remark-gfm';
7+
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
8+
import { materialOceanic } from 'react-syntax-highlighter/dist/cjs/styles/prism';
9+
import Layout from 'components/Layout';
10+
import headerColor from 'helpers/post-header';
11+
import styles from 'styles/post.module.scss';
12+
import ProgressiveImage from 'components/ProgressiveImage';
13+
import isExternalImage from 'helpers/is-external-image';
14+
import generateArticleStructuredData from 'helpers/generate-article-structured-data';
15+
import generateFaqStructuredData from 'helpers/generate-faq-structured-data';
16+
17+
export default function BlogPost({
18+
siteTitle,
19+
frontmatter,
20+
markdownBody,
21+
date,
22+
slug,
23+
image
24+
}) {
25+
// eslint-disable-next-line react/jsx-no-useless-fragment
26+
if (!frontmatter) return <></>;
27+
28+
return (
29+
<Layout
30+
socialMeta={{
31+
url: `blog/${slug}`,
32+
image,
33+
imageAlt: frontmatter.cover_image_alt,
34+
type: 'article',
35+
title: `${frontmatter.title} | ${siteTitle}`,
36+
description: frontmatter.description
37+
}}
38+
breadcrumbs={[
39+
{ name: 'blog', item: 'blog/' },
40+
{ name: frontmatter.title, item: `blog/${slug}` }
41+
]}
42+
structured={[
43+
generateFaqStructuredData(frontmatter.faq),
44+
generateArticleStructuredData({
45+
title: frontmatter.title,
46+
slug,
47+
description: frontmatter.description,
48+
image,
49+
date
50+
})
51+
]}
52+
>
53+
<article className={styles.post}>
54+
{frontmatter.cover_image ? (
55+
<ProgressiveImage
56+
className={styles.post__header__image}
57+
src={frontmatter.cover_image}
58+
alt={frontmatter.cover_image_alt}
59+
/>
60+
) : (
61+
<div
62+
className={styles.post__header__image}
63+
style={{ backgroundColor: headerColor }}
64+
/>
65+
)}
66+
<div className='container'>
67+
<div className={styles.post__header__title}>
68+
<h2>{frontmatter.title}</h2>
69+
<div className={styles.post__date_label}>{date}</div>
70+
</div>
71+
</div>
72+
<div className={styles.post__body}>
73+
<div className='container'>
74+
<div className={styles.post__intro}>{frontmatter.intro}</div>
75+
<ReactMarkdown
76+
remarkPlugins={[remarkGfm]}
77+
components={{
78+
// eslint-disable-next-line react/no-unstable-nested-components
79+
code({ inline, className, children }) {
80+
const match = /language-(\w+)/.exec(className || '');
81+
82+
return !inline && match ? (
83+
<SyntaxHighlighter
84+
style={materialOceanic}
85+
language={match[1]}
86+
>
87+
{String(children).replace(/\n$/, '')}
88+
</SyntaxHighlighter>
89+
) : (
90+
<code className={className}>{children}</code>
91+
);
92+
},
93+
img: ProgressiveImage
94+
}}
95+
>
96+
{markdownBody}
97+
</ReactMarkdown>
98+
</div>
99+
</div>
100+
</article>
101+
</Layout>
102+
);
103+
}
104+
105+
BlogPost.propTypes = {
106+
siteTitle: PropTypes.string,
107+
frontmatter: PropTypes.object,
108+
markdownBody: PropTypes.string,
109+
date: PropTypes.array,
110+
slug: PropTypes.string,
111+
image: PropTypes.string
112+
};
113+
114+
export async function getStaticProps({ ...ctx }) {
115+
const { postname } = ctx.params;
116+
const content = await import(`../../posts/${postname}.md`);
117+
const config = await import('../../siteconfig.json');
118+
const date = postname.match(/(\d{1,4}([.\--])\d{1,2}([.\--])\d{1,4})/g);
119+
const data = matter(content.default);
120+
let image = data.data.cover_image || null;
121+
122+
if (image && !isExternalImage(image)) {
123+
const src = require(`images/${data.data.cover_image}`);
124+
125+
image = 'https://khendrikse.github.io'.concat(src.src);
126+
}
127+
128+
return {
129+
props: {
130+
siteTitle: config.title,
131+
frontmatter: data.data,
132+
markdownBody: data.content,
133+
date,
134+
slug: postname,
135+
image
136+
}
137+
};
138+
}
139+
140+
export async function getStaticPaths() {
141+
const blogSlugs = (context => {
142+
const keys = context.keys();
143+
const data = keys.map(key => {
144+
const slug = key.replace(/^.*[\\/]/, '').slice(0, -3);
145+
146+
return slug;
147+
});
148+
149+
return data;
150+
})(require.context('../../posts', true, /\.\/.*\.md$/));
151+
152+
const paths = blogSlugs.map(slug => `/blog/${slug}`);
153+
154+
return {
155+
paths,
156+
fallback: false
157+
};
158+
}

pages/blog/[categoryname].js pages/blog/category/[categoryname].js

+7-7
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ const Index = props => (
1515
{...props}
1616
socialMeta={{
1717
...socialMeta,
18-
url: `blog/${props.currentCategory}`,
18+
url: `blog/category/${props.currentCategory}`,
1919
description: `Blog about ${props.currentCategory}`,
2020
title: props.title
2121
}}
22-
breadcrumbs={[{ name: 'blog', item: `blog/${props.currentCategory}` }]}
22+
breadcrumbs={[{ name: 'blog', item: `blog/category/${props.currentCategory}` }]}
2323
/>
2424
);
2525

@@ -33,13 +33,13 @@ export default Index;
3333
export async function getStaticProps({ ...ctx }) {
3434
const { categoryname } = ctx.params;
3535
const allPosts = parsePosts(
36-
require.context('../../posts', true, /\.\/.*\.md$/)
36+
require.context('../../../posts', true, /\.\/.*\.md$/)
3737
);
3838

3939
const categories = getCategories(allPosts);
4040
const posts = allPosts.filter(post => post?.tags?.includes(categoryname));
4141

42-
const config = await import('../../siteconfig.json');
42+
const config = await import('../../../siteconfig.json');
4343

4444
return {
4545
props: {
@@ -56,14 +56,14 @@ export async function getStaticPaths() {
5656
const keys = context.keys();
5757
const data = keys
5858
.map(key => key.replace(/^.*[\\/]/, '').slice(0, -3))
59-
.map(key => import(`../../posts/${key}.md`));
59+
.map(key => import(`../../../posts/${key}.md`));
6060

6161
const allPosts = await Promise.all(data);
6262
return allPosts.map(post => matter(post.default).data);
63-
})(require.context('../../posts', true, /\.\/.*\.md$/));
63+
})(require.context('../../../posts', true, /\.\/.*\.md$/));
6464
const categorySlugs = getCategories(posts);
6565

66-
const paths = categorySlugs.map(slug => `/blog/${slug}`);
66+
const paths = categorySlugs.map(slug => `/blog/category/${slug}`);
6767

6868
return {
6969
paths,

0 commit comments

Comments
 (0)