The Node.js® Website
1import { getTranslations } from 'next-intl/server';
2import type { FC } from 'react';
3
4import { getClientContext } from '@/client-context';
5import BlogHeader from '@/components/Blog/BlogHeader';
6import WithBlogCategories from '@/components/withBlogCategories';
7import WithFooter from '@/components/withFooter';
8import WithNavBar from '@/components/withNavBar';
9import getBlogData from '@/next-data/blogData';
10
11import styles from './layouts.module.css';
12
13const getBlogCategory = async (pathname: string) => {
14 // pathname format can either be: /en/blog/{category}
15 // or /en/blog/{category}/page/{page}
16 // hence we attempt to interpolate the full /en/blog/{category}/page/{page}
17 // and in case of course no page argument is provided we define it to 1
18 // note that malformed routes can't happen as they are all statically generated
19 const [, , category = 'all', , page = 1] = pathname.split('/');
20
21 const { posts, pagination } = await getBlogData(category, Number(page));
22
23 return { category, posts, pagination, page: Number(page) };
24};
25
26const BlogLayout: FC = async () => {
27 const { pathname } = getClientContext();
28 const t = await getTranslations();
29
30 const mapCategoriesToTabs = (categories: Array<string>) =>
31 categories.map(category => ({
32 key: category,
33 label: t(`layouts.blog.categories.${category}`),
34 link: `/blog/${category}`,
35 }));
36
37 const blogData = await getBlogCategory(pathname);
38
39 return (
40 <>
41 <WithNavBar />
42
43 <div className={styles.blogLayout}>
44 <main>
45 <BlogHeader category={blogData.category} />
46
47 <WithBlogCategories
48 blogData={blogData}
49 categories={mapCategoriesToTabs([
50 'all',
51 'announcements',
52 'release',
53 'vulnerability',
54 ])}
55 />
56 </main>
57 </div>
58
59 <WithFooter />
60 </>
61 );
62};
63
64export default BlogLayout;