The Software that replaces modern CMS and content compilers like Contentlayer
Tags: javascript, programming, node, tutorial
Published: 2024-07-01 10:23:32

If you don't know Contenthook yet, then I got you covered. In this Tutorial, we will be setting up a Next.js X Contenthook project and build an easy blog system.

But Foremost, what is Contenthook Exactly?
> Contenthook is a very powerful content compiler working with a cloud. When setting a project up, you are asked to create a local content path. In this folder you can create MD, MDX, and Markdown files. With the Contenthook push command, you can push the content to the cloud. The cloud will then compile the content and send it to our content file registry. Now you can import the content fetch functions in your Backend project like a Node.js project or in a frontend project, for example with Vue.js, Next.js, etc. This way, you can easily manage your content through the cloud and locally, and have a clear overview of your project.

## Set up a new Next.js project.
Use the below command.
```bash
npx create-next-app
```

> [WARNING]
> Make sure to not choose TypeScript as it would break the Tutorial and make sure to choose TailwindCSS as it will be needed later.

Go through the questions.

## Setup Contenthook
## Create API Key
Firstly, go to https://www.contenthook.dev and register. Once you have been registered, create a new API Key on the [dashboard](https://www.contenthook.dev/dashboard).

## Set up the actual Contenthook 
CD into your Next.js app folder and inside the folder run:
```bash
npm i contenthook
```
and after that, use the Contenthook CLI to get started.
```bash
contenthook init
```
Answer the desired questions and for the ``contenthook.config.js`` file, choose ``import/export`` and as extension ``mjs``.
When it asks you for the API Key, paste in or enter the API Key you obtained from the Contenthook dashboard. And make sure to not share the API Key with anyone!!

## Install the Contenthook browser SDK
Now to be able to fetch your contents, run:
```bash
npm i @contenthook/browser 
```

## Set up the ContentMetaData API
Now, to be able to use metadata in your Markdown files, insert the below code at the top of your ``contenthook.config.mjs`` file.
```js
export const ContentMetaData = {
  title: String,
  description: String,
  date: Date,
  tags: [String],
};
```

## Create your Markdown files.
Create your first markdown file in the selected content directory. Create a file called ``example.md`` with the below content:
```markdown
---
title: example post
description: This is a example post
date: 2024-01-07
tags: [example, post]
---

# Example Post

> Hello!
> This is the content of the example post. You can write your MDX content here.
```

## Push your content to the Cloud
In the next step, we are pushing the contents to the Contenthook cloud. Run the below command in the project root of your Next.js app.
```
contenthook push
```
Now you can also view and edit your content files from the cloud / dashboard. See the "Content" section of your API Key on the dashboard. When you edit your content from the dashboard, don't forget to pull your contents again to your local project:
```
contenthook pull
```

## Setup Typography with TailwindCSS
First of all, install their library:
```bash
npm install -D @tailwindcss/typography
```
After that, add the plugin to your ``tailwind.config.js`` file:
```js
/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    // ...
  },
  plugins: [
    require('@tailwindcss/typography'),
    // ...
  ],
}
```

# Use Contenthook in the project root directory
Now create a new file inside your app directory.
Create the file ``./app/post/page.js``:
```jsx
"use client";

import React, { useEffect, useState } from "react";
import { getContents } from "@contenthook/browser";

const Post = () => {
    const [content, setContent] = useState({});

    useEffect(() => {
        const fetchContent = async () => {
            const content = await getContents({ api_key: "YOUR_API_KEY" });
            console.log(content);
            setContent(content[0]); // As we only use one content in this example.
            // You can also use special ID's or slugs to get a specific content.
        };

        fetchContent();
    }, []);

    return (
        <div className="items-center justify-center min-h-screen w-full flex flex-col p-6">
            {content.title ? (<>
                <h1 className="text-4xl font-bold">{content.metadata.title}</h1>
                <p className="text-lg">{content.metadata.description}</p>

                <div className="mt-4">
                    <ul className="flex">
                        {content.metadata.tags.map((tag, index) => (
                            <li key={index} className="ml-2 bg-blue-400/20 p-2 rounded-md">{tag}</li>
                        ))}
                    </ul>
                </div>

                <article class="prose lg:prose-xl prose-invert mt-12">
                    <div dangerouslySetInnerHTML={{ __html: content.html }} />
                </article>
            </>) : (
                <p>Loading...</p>
            )}
        </div>
    );
};

export default Post;
```

And that's it! Now you are using Contenthook in your project! 🥳