Skip to content

rick-liyue-huang/contentlayer-demo

Repository files navigation

title description author publishedDate date
Build a Personal Site with ContentLayer and ChakraUI
build a personal site with contentlayer and chakraui and host by amplify
haimtran
08/12/2022
2022-08-12

Build a Personal Site with ContentLayer and ChakraUI

  • Contentlayer converts mdx, md into json and react components
  • Contentlayer does routing - nextjs prerender
  • Contentlayer appiles styles to generated components
  • Provide styles via ChakaraUI and useMDXComponent hook
  • GitHub

Create NextJS App

npx create-next-app@latest my-site --typescript

add content layer

npm install contentlayer next-contentlayer

add chakraui

npm i @chakra-ui/react @emotion/react @emotion/styled framer-motion
|--.contentlayer
|--pages
   |___app.tsx
   |__index.tsx
   |--posts
      |--[slug].js
|--posts
   |--post-01.mdx
   |--post-02.mdx
   |--post-03.mdx
|--src
   |--components
      |--mdx-components
         |--codeblock
         |--inline-code.tsx
         |--linked-heading.tsx
         |--mdx-component.tsx
|--contentlayer.config.js
|--next.config.js
|--package.json

configure tsconfig with paths

{
  "compilerOptions": {
    ...
    "incremental": true,
    "baseUrl": "."
  },
  "paths": {
    "contentlayer/generated": ["./.contentlayer/generated"],
    "styles/*": ["styles/*"]
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    ".contentlayer/generated"
  ],
  "exclude": ["node_modules"]
}

configure next.config.js

const { withContentlayer } = require("next-contentlayer");
module.exports = withContentlayer({});

Configure Schema

This is the content of contentlayer.config.js and it specifies the schema of Post. Given the schema, contentlayer can convert md, mdx content into react components.

import { defineDocumentType, makeSource } from "contentlayer/source-files";

export const Post = defineDocumentType(() => ({
  name: "Post",
  filePathPattern: `**/*.mdx`,
  contentType: "mdx",
  fields: {
    title: {
      type: "string",
      description: "The title of the post",
      required: true,
    },
    description: {
      type: "string",
    },
    date: {
      type: "date",
      description: "The date of the post",
      required: true,
    },
  },
  computedFields: {
    url: {
      type: "string",
      resolve: (post) => `/posts/${post._raw.flattenedPath}`,
    },
  },
}));

export default makeSource({
  contentDirPath: "posts",
  documentTypes: [Post],
});

Configure Routes

import the generated posts from contentlayer and map to the nextjs url

import { allPosts } from "./../../.contentlayer/generated";

export async function getStaticPaths() {
  const paths = allPosts.map((post) => post.url);
  return {
    paths,
    fallback: false,
  };
}

match the request url (from user) with the nextjs url using slug.

export async function getStaticProps({ params }) {
  const post = allPosts.find((post) => post._raw.flattenedPath === params.slug);
  return {
    props: {
      post,
    },
  };
}

Apply Styles

Provide styles for generated components via MDXComponents. For example

const mdxComponents = {
  h1: (props) => <chakra.h1 fontSize={"5xl"} apply="mdx.h1" {...props} />,
  h2: (props) => <chakra.h2 fontSize={"3xl"} apply="mdx.h2" {...props} />,
};

Then apply the styles into generated components

import React from "react";
import { allPosts } from ".contentlayer/generated";
import { useMDXComponent } from "next-contentlayer/hooks";
import { Box, chakra } from "@chakra-ui/react";
import styles from "styles/Home.module.css";

const PostLayout = ({ post }) => {
  const MDXContent = useMDXComponent(post.body.code);

  return (
    <Box bg={"gray.100"} maxW="1000px" margin={"auto"} padding="20px">
      <div>
        <h1 className={styles.title}>{post.title}</h1>
        <MDXContent components={mdxComponents}></MDXContent>
      </div>
    </Box>
  );
};

export default PostLayout;

Amplify Hosting

amplify init

then add hosting

amplify add hosting

select manual then publish (this work for static website). For hybrid, need to choose CI/CD pipeline with GitHub source or using vercel hosting.

amplify publish

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published