Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
October 28, 2022 02:41 pm GMT

How to Create a Blog with NextJS, Notion, and Notion API

In this post, I want to try how we can create a blog management system using notion as a database. I have created a post onhow to create a blog with airtable, I used airtable in that project. Now I'm doing it with notion.

I wrote this post to my own blog first, and I want to publish it here too.

At first, we can find everything about notion;https://developers.notion.com/address

Create a Notion Integration for Our Blog

I have looked at the documentation and let's start. Firstly we should create an integration fromhttps://www.notion.so/my-integrations

notion

Create a new integration on this page. I have created an integration named myblog, and these are my settings;

basic information

After these steps notion will give you a notion token, copy this token to a secure place, and we will use it for connecting our data.

After that, we have to create a page and convert it to a database to use for our blog. I have created a notion page -- database full page. This is what I get;

new

There is a share button top right, Click on theSharebutton and use the selector to find your integration by its name, then clickInvite.

Our integration has an access to our database now, last step we need the database id. It's the part of your URL;

Mine is;https://www.notion.so/yunuserturk/f9dfc334e89e4c2289b9bc98884b5e80

And the database id is;f9dfc334e89e4c2289b9bc98884b5e80

Now we have to create our app and we can use these notion access.

Create a NextJS App

The easiest way to get started with Next.js is by usingcreate-next-app.

Create a project with VS Code, open the terminal and use the command;npx create-next-app

Install tailwindcss;

npm install -D tailwindcss postcss autoprefixernpx tailwindcss init -p

Create a sketchy UI, I copied the code from the airtable project.

import Head from "next/head";export default function Home() {  return (    <div>      <Head>        <title>Create Next App</title>        <meta name="description" content="Generated by create next app" />        <link rel="icon" href="https://dev.to/favicon.ico" />      </Head>      <main>        <div className="container mx-auto w-full sm:w-10/12 md:w-8/12 lg:w-6/12 xl:w-6/12 p-4">          <h1 className="font-bold text-2xl">Welcome to my blog</h1>          <div className="flex flex-col p-5 rounded-lg border-2 border-gray-200 mt-10">            <h2 className="text-xl font-bold">Post Title</h2>            <div>Post Content will be here</div>            <span className="text-sm mb-6">Post Date</span>          </div>        </div>      </main>    </div>  );}

How to Use Notion API and Show the Content

Our homepage is ready, now we have to fetch the data to show it on our page. Let's install notion client SDK withnpm install @notionhq/client, run this command on terminal. Create a filelib>notion.jsand we will use our database here. With the help of the documentation, I created a starter code.

import { Client } from "@notionhq/client";const notion = new Client({  auth: process.env.NEXT_PUBLIC_NOTION_TOKEN,});export const getDatabase = async (databaseId) => {  const response = await notion.databases.query({    database_id: databaseId,  });  return response.results;};export const getPage = async (pageId) => {  const response = await notion.pages.retrieve({ page_id: pageId });  return response;};export const getBlocks = async (blockId) => {  const blocks = [];  let block;  while (true) {    const { results, next_block } = await notion.blocks.children.list({      start_block: block,      block_id: blockId,    });    blocks.push(...results);    if (!next_block) {      break;    }    block = next_block;  }  return blocks;}

We'll import this to the index page and fetch the data and show the posts on the home page. With the notion API, getpage function only fetches the properties of the page. We can't retrieve the page blocks. We have to create another function and use API for retrieving page content. Notion called them blocks and has another function for it.

My final index.js page is like that;

import Head from "next/head";import { getDatabase } from "../lib/notion";import Link from "next/link";export default function Home({ posts }) {  return (    <div>      <Head>        <title>Create Next App</title>        <meta name="description" content="Generated by create next app" />        <link rel="icon" href="https://dev.to/favicon.ico" />      </Head>      <main>        <div className="container mx-auto w-full sm:w-10/12 md:w-8/12 lg:w-6/12 xl:w-6/12 p-4">          <h1 className="font-bold text-2xl">Welcome to my blog</h1>          {posts.map((post) => {            const date=new Date(post.created_time).toLocaleString("en-Us",{              month: "long",              day: "numeric",              year: "numeric",              })            return (              <div className="flex flex-col p-5 rounded-lg border-2 border-gray-200 mt-10" key={post.id}>                <h2 className="text-xl font-bold">{post.properties.Name.title[0].plain_text}</h2>                <span className="text-sm">{date}</span>                <Link href="https://dev.to/[post]" as={`/${post.id}`}>                  <a className="text-sm">Read more</a>                </Link>              </div>            );          })}        </div>      </main>    </div>  );}export const getStaticProps = async () => {  const database = await getDatabase("f9dfc334e89e4c2289b9bc98884b5e80");  return {    props: {      posts: database,    },    revalidate: 1,  };};

Notion gives us the blocks with API with plenty of properties. As you wish you can use which of them you want. But I just use the text and just for these blocks; paragraphs and headers. You can adjust the blocks you will use according to the project you are doing. (We will use it on the single post page.)

Here is the single post page file;

import { getDatabase, getPage, getBlocks } from "../lib/notion";import Head from "next/head";const renderBlock = (block) => {  const { type } = block;  const value = block[type];  switch (type) {    case "paragraph":      return <p className="mb-4">{value.rich_text[0].plain_text}</p>;    case "heading_1":      return <h1 className="font-bold text-3xl  mb-2">{value.rich_text[0].plain_text}</h1>;    case "heading_2":      return <h2 className="font-bold text-2xl  mb-2">{value.rich_text[0].plain_text}</h2>;    case "heading_3":      return <h3 className=" font-bold text-xl mb-2">{value.rich_text[0].plain_text}</h3>;  }};export default function Post({ post, content }) {  const date = new Date(post.created_time).toLocaleString("en-Us", {    month: "long",    day: "numeric",    year: "numeric",  });  return (    <div>      <Head>        <title>{post.properties.Name.title[0].plain_text}</title>        <link rel="icon" href="https://dev.to/favicon.ico" />      </Head>      <main>        <div className="container mx-auto w-full sm:w-10/12 md:w-8/12 lg:w-6/12 xl:w-6/12 p-4">          <h1 className="font-bold text-2xl">{post.properties.Name.title[0].plain_text}</h1>          <span className="text-sm">{date}</span>          <img src="<https://picsum.photos/800/200>" alt="random image" className=" max-w-full" />          <div className="mt-10">            {content.map((block) => {              console.log(block);              return <div key={block.id}>{block.type === "page_break" ? <hr /> : <div>{renderBlock(block)}</div>}</div>;            })}          </div>        </div>      </main>    </div>  );}export const getStaticPaths = async () => {  const database = await getDatabase("f9dfc334e89e4c2289b9bc98884b5e80");  const paths = database.map((post) => {    return {      params: {        post: post.id,      },    };  });  return {    paths,    fallback: false,  };};export const getStaticProps = async ({ params }) => {  const postId = params.post;  const post = await getPage(postId);  const content = await getBlocks(postId);  return {    props: {      post,      content,    },    revalidate: 1,  };};

Here is the final post page;

final

Deployment and the result

I deployed it to vercel finally. It's a very basic use of Nation API, If you create something more different you can use it this way.

You can see al the code from the github repo:https://github.com/yunuserturk/notion-blog

Here is the demo of final result:https://notion-blog-yunuserturk.vercel.app/


Original Link: https://dev.to/yunuserturk/how-to-create-a-blog-with-nextjs-notion-and-notion-api-4fnm

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To