No fallback path for blog posts
This commit is contained in:
parent
0300666591
commit
e644b48c3b
3
.babelrc
3
.babelrc
|
@ -11,6 +11,9 @@
|
|||
["tailwind", { "ssr": true, "displayName": true, "preprocess": false }]
|
||||
],
|
||||
"presets": ["next/babel"]
|
||||
},
|
||||
"test": {
|
||||
"presets": ["@babel/preset-env", "@babel/preset-react"]
|
||||
}
|
||||
},
|
||||
"plugins": [
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
"react-dom": "^17.0.1",
|
||||
"react-paginate": "^7.1.0",
|
||||
"react-redux": "^7.2.1",
|
||||
"react-scripts": "^4.0.2",
|
||||
"react-use": "^17.1.1",
|
||||
"redux": "^4.0.5",
|
||||
"swr": "^0.3.9",
|
||||
|
@ -57,6 +58,9 @@
|
|||
"vercel": "^20.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.17",
|
||||
"@babel/preset-env": "^7.12.17",
|
||||
"@babel/preset-react": "^7.12.13",
|
||||
"@types/lodash.get": "^4.4.6",
|
||||
"@types/lodash.set": "^4.3.6",
|
||||
"@types/node": "^14.14.28",
|
||||
|
@ -64,6 +68,7 @@
|
|||
"@typescript-eslint/eslint-plugin": "^3.9.0",
|
||||
"@typescript-eslint/parser": "^3.9.0",
|
||||
"autoprefixer": "^10.2.4",
|
||||
"babel-jest": "^26.6.3",
|
||||
"eslint": "^7.7.0",
|
||||
"eslint-config-prettier": "^6.11.0",
|
||||
"eslint-plugin-prettier": "^3.1.4",
|
||||
|
|
|
@ -19,27 +19,28 @@ export async function getStaticPaths() {
|
|||
let foundAllPosts = false;
|
||||
|
||||
// Contentful only allows 100 at a time
|
||||
try {
|
||||
while (!foundAllPosts) {
|
||||
const { posts: _posts } = await api.fetchBlogEntries(100, page);
|
||||
while (!foundAllPosts) {
|
||||
const { posts: _posts } = await api.fetchBlogEntries(100, page);
|
||||
|
||||
if (_posts.length === 0) {
|
||||
foundAllPosts = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
posts = [...posts, ..._posts];
|
||||
page++;
|
||||
if (_posts.length === 0) {
|
||||
foundAllPosts = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
const paths: IPath[] = posts.map(item => ({
|
||||
params: { slug: item.slug },
|
||||
}));
|
||||
console.log('[slug] ➡️ page:', page);
|
||||
console.log('[slug] ➡️ foundAllPosts:', foundAllPosts);
|
||||
console.log('[slug] ➡️ _posts.length:', _posts.length);
|
||||
console.log('[slug] ➡️ posts.length:', posts.length);
|
||||
|
||||
return { paths, fallback: true };
|
||||
} catch (e) {
|
||||
return { paths: [], fallback: true };
|
||||
posts = [...posts, ..._posts];
|
||||
page++;
|
||||
}
|
||||
|
||||
const paths: IPath[] = posts.map(item => ({
|
||||
params: { slug: item.slug },
|
||||
}));
|
||||
|
||||
return { paths, fallback: false };
|
||||
}
|
||||
|
||||
export async function getStaticProps({ params }) {
|
||||
|
@ -77,14 +78,14 @@ function Post({ post }: { post: IPost }) {
|
|||
<title>{pageTitle}</title>
|
||||
<meta
|
||||
property="og:image"
|
||||
content={post.featureImage.imageUrl}
|
||||
content={post?.featureImage.imageUrl}
|
||||
key="ogimage"
|
||||
/>
|
||||
<meta property="og:site_name" content="oxen.io" key="ogsitename" />
|
||||
<meta property="og:title" content={pageTitle} key="ogtitle" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content={post.description}
|
||||
content={post?.description}
|
||||
key="ogdesc"
|
||||
/>
|
||||
</Head>
|
||||
|
|
|
@ -1,16 +1,119 @@
|
|||
import { createClient } from 'contentful';
|
||||
import dotenv from 'dotenv';
|
||||
import { getStaticPaths } from '../pages/[page]';
|
||||
import moment from 'moment';
|
||||
import { CMS } from '../constants';
|
||||
import { IAuthor, IFigureImage, IPost } from '../types/cms';
|
||||
|
||||
interface IPath {
|
||||
params: { slug: string };
|
||||
}
|
||||
|
||||
interface IFetchBlogEntriesReturn {
|
||||
posts: Array<IPost>;
|
||||
total: number;
|
||||
}
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const client = createClient({
|
||||
space: process.env.CONTENTFUL_SPACE_ID,
|
||||
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,
|
||||
});
|
||||
|
||||
const convertPost = (rawData): IPost => {
|
||||
const rawPost = rawData.fields;
|
||||
const rawFeatureImage = rawPost?.featureImage
|
||||
? rawPost?.featureImage.fields
|
||||
: null;
|
||||
const rawAuthor = rawPost.author ? rawPost.author.fields : null;
|
||||
|
||||
return {
|
||||
id: rawData.sys.id ?? null,
|
||||
body: rawPost.body ?? null,
|
||||
subtitle: rawPost.subtitle ?? null,
|
||||
description: rawPost.description ?? null,
|
||||
publishedDate: moment(rawPost.date).format('DD MMMM YYYY'),
|
||||
slug: rawPost.slug,
|
||||
tags: rawPost?.tags, //?.map(t => t?.fields?.label) ?? [],
|
||||
title: rawPost.title,
|
||||
featureImage: convertImage(rawFeatureImage),
|
||||
author: convertAuthor(rawAuthor),
|
||||
};
|
||||
};
|
||||
|
||||
const convertImage = (rawImage): IFigureImage =>
|
||||
rawImage
|
||||
? {
|
||||
imageUrl: rawImage.file.url.replace('//', 'http://'), // may need to put null check as well here
|
||||
description: rawImage.description ?? null,
|
||||
title: rawImage.title ?? null,
|
||||
}
|
||||
: null;
|
||||
|
||||
const convertAuthor = (rawAuthor): IAuthor =>
|
||||
rawAuthor
|
||||
? {
|
||||
name: rawAuthor?.name ?? null,
|
||||
avatar: convertImage(rawAuthor.avatar.fields),
|
||||
shortBio: rawAuthor?.shortBio ?? null,
|
||||
position: rawAuthor?.position ?? null,
|
||||
email: rawAuthor?.email ?? null,
|
||||
twitter: rawAuthor?.twitter ?? null,
|
||||
facebook: rawAuthor.facebook ?? null,
|
||||
github: rawAuthor.github ?? null,
|
||||
}
|
||||
: null;
|
||||
|
||||
const fetchBlogEntries = async (
|
||||
quantity = CMS.BLOG_RESULTS_PER_PAGE,
|
||||
page = 1,
|
||||
): Promise<IFetchBlogEntriesReturn> => {
|
||||
console.log('cms ➡️ page:', page);
|
||||
console.log('cms ➡️ quantity:', quantity);
|
||||
console.log('cms ➡️ (page - 1) * quantity:', (page - 1) * quantity);
|
||||
|
||||
try {
|
||||
const entries = await client.getEntries({
|
||||
content_type: 'post', // only fetch blog post entry
|
||||
order: '-fields.date',
|
||||
limit: quantity,
|
||||
skip: (page - 1) * quantity,
|
||||
});
|
||||
|
||||
if (entries && entries.items && entries.items.length > 0) {
|
||||
const blogPosts = entries.items.map(entry => convertPost(entry));
|
||||
return { posts: blogPosts, total: entries.total };
|
||||
}
|
||||
|
||||
return { posts: [], total: 0 } as IFetchBlogEntriesReturn;
|
||||
} catch (e) {
|
||||
return { posts: [], total: 0 } as IFetchBlogEntriesReturn;
|
||||
}
|
||||
};
|
||||
|
||||
describe('getStaticPaths', () => {
|
||||
test('', async () => {
|
||||
const { paths: postPaths } = await getStaticPaths();
|
||||
let posts: IPost[] = [];
|
||||
let page = 1;
|
||||
let foundAllPosts = false;
|
||||
|
||||
console.log('getStaticPaths.test ➡️ postPaths:', postPaths);
|
||||
// Contentful only allows 100 at a time
|
||||
while (!foundAllPosts) {
|
||||
const { posts: _posts } = await fetchBlogEntries(100, page);
|
||||
|
||||
if (_posts.length === 0) {
|
||||
foundAllPosts = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
posts = [...posts, ..._posts];
|
||||
page++;
|
||||
}
|
||||
|
||||
const paths: IPath[] = posts.map(item => ({
|
||||
params: { slug: item.slug },
|
||||
}));
|
||||
|
||||
console.log('getStaticPaths.test ➡️ postPaths:', paths);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue