diff --git a/content/posts/hello-world.md b/content/posts/hello-world.md
index 0c784c8ae..74312ab4d 100644
--- a/content/posts/hello-world.md
+++ b/content/posts/hello-world.md
@@ -2,6 +2,8 @@
title: 'Mapping Public Toilets'
author: 'Ollie'
date: 2024-04-16T19:31:20.591Z
+profilePictureUrl: https://avatars.githubusercontent.com/u/1771189?v=4
+profileSocialUrl: https://olliethinks.co.uk/
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vitae placerat leo, non posuere justo. Nulla facilisi. Vivamus ac tempus justo, a volutpat eros. Ut felis magna, semper nec felis non, finibus euismod eros. Vestibulum congue tellus ut augue mattis ullamcorper. Sed et libero eget sapien sollicitudin auctor. Maecenas accumsan pretium neque sed euismod. Nam facilisis felis a massa blandit dictum. Maecenas finibus pretium odio id aliquam. Aenean vel odio nec tellus rutrum hendrerit a quis nisi.
diff --git a/contentlayer.config.ts b/contentlayer.config.ts
index c6c3dd3dd..7306a409d 100644
--- a/contentlayer.config.ts
+++ b/contentlayer.config.ts
@@ -7,6 +7,8 @@ export const Post = defineDocumentType(() => ({
title: { type: 'string', required: true },
date: { type: 'date', required: true },
author: { type: 'string', required: true },
+ profileSocialUrl: { type: 'string', required: false },
+ profilePictureUrl: { type: 'string', required: false },
},
computedFields: {
url: {
diff --git a/next.config.js b/next.config.js
index f0ee25f21..2f18f0a2e 100644
--- a/next.config.js
+++ b/next.config.js
@@ -3,6 +3,9 @@
**/
const moduleExports = {
reactStrictMode: true,
+ images: {
+ remotePatterns: [{ hostname: 'avatars.githubusercontent.com' }],
+ },
typescript: {
// !! WARN !!
// Dangerously allow production builds to successfully complete even if
diff --git a/public/admin/config.yml b/public/admin/config.yml
index f2576124b..6ae9f8cee 100644
--- a/public/admin/config.yml
+++ b/public/admin/config.yml
@@ -30,4 +30,6 @@ collections:
- { label: "Title", name: "title", widget: "string"}
- { label: "Publish Date", name: "date", widget: "datetime" }
- { label: "Author", name: "author", widget: "string" }
+ - { label: "Social URL", name: "profileSocialUrl", widget: "string" }
+ - { label: "Profile Image URL", name: "profilePictureUrl", widget: "string" }
- { label: "Body", name: "body", widget: "markdown" }
diff --git a/src/components/Header/MainMenu.tsx b/src/components/Header/MainMenu.tsx
index 06a961ea8..3e7c0cdc2 100644
--- a/src/components/Header/MainMenu.tsx
+++ b/src/components/Header/MainMenu.tsx
@@ -107,7 +107,7 @@ const MainMenu = ({ children }: IMainMenu) => {
- Blog
+ Blog
{user && (
diff --git a/src/pages/posts/[slug]/index.page.tsx b/src/pages/posts/[slug]/index.page.tsx
index 5990b7c8b..acdc9cd61 100644
--- a/src/pages/posts/[slug]/index.page.tsx
+++ b/src/pages/posts/[slug]/index.page.tsx
@@ -1,31 +1,41 @@
+import React from 'react';
+
import { allPosts, Post } from 'contentlayer/generated';
import { format, parseISO } from 'date-fns';
import Head from 'next/head';
-import React from 'react';
+import Image from 'next/image';
import Box from '../../../components/Box';
import Container from '../../../components/Container';
import Spacer from '../../../components/Spacer';
import Text from '../../../components/Text';
import { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from 'next';
+import Link from 'next/link';
-// export const generateMetadata = ({ params }: { params: { slug: string } }) => {
-// const post = allPosts.find((post) => post._raw.flattenedPath === params.slug);
-// if (!post) throw new Error(`Post not found for slug: ${params.slug}`);
-// return { title: post.title };
-// };
+export const generateMetadata = ({ params }: { params: { slug: string } }) => {
+ const post = allPosts.find(
+ (post) => post._raw.flattenedPath.split('posts/')[1] === params?.slug,
+ );
+ if (!post) throw new Error(`Post not found for slug: ${params.slug}`);
+ return { title: post.title };
+};
export const getStaticPaths = (async () => {
return {
paths: allPosts.map((post) => ({
params: { slug: post._raw.flattenedPath.split('posts/')[1] },
})),
- fallback: true, // false or "blocking"
+ fallback: true,
};
}) satisfies GetStaticPaths;
-export const getStaticProps = (async (context) => {
+type Props = {
+ postData: Post;
+ notFound?: boolean;
+};
+
+export const getStaticProps: GetStaticProps = (async (context) => {
const postData = allPosts.find(
(post) =>
post._raw.flattenedPath.split('posts/')[1] === context?.params?.slug,
@@ -35,16 +45,13 @@ export const getStaticProps = (async (context) => {
if (!postData) return { props: { postData: null, notFound: true } };
return { props: { postData } };
-}) satisfies GetStaticProps<{
- postData: Post;
- notFound?: boolean;
-}>;
+}) satisfies GetStaticProps;
export default function PostPage({
postData,
notFound,
}: InferGetStaticPropsType) {
- if (notFound) return null;
+ if (notFound || postData === null) return null;
return (
@@ -54,10 +61,29 @@ export default function PostPage({
{postData.title}
{' '}
-
-
- {postData.author}
-
+ {postData?.profilePictureUrl && (
+ <>
+
+
+
+ >
+ )}
+
+
+ {postData.author}
+
+