Getting Started with Next.js and BCMS

This guide will show you how to integrate BCMS with a Next.js project. Let's begin!

The fastest way to go from 0 to a simple Next.js blog + BCMS is to locally run

npx @thebcms/cli create next starter simple-blog

and follow the prompts.

The command will:

  • Create a new BCMS project

  • Populate it with some simple content

  • Create a scaffold Next.js project locally

  • Create an .env file and update codebase with necessary BCMS config

Afterward, just run

npm install
npm run dev

Alternatively, if you want a step-by-step process, here it is:


Open your BCMS project

Go to https://app.thebcms.com. Make sure you have some entries in your BCMS project to fetch and display in Next.js. For example, create a template called Blog and add a media property called Cover Image.

1.png

Create a Blog Entry

Create a new blog entry with the title My First Blog, add a cover image, and write some content (e.g., lorem ipsum).

2.png

Create an API Key

Navigate to Administration > Settings > API Keys. Create a new API key. Ensure the key has permission to access entries from the Blog template. Create one more key, call it "Public". Do not give it any additional permissions. We'll use it for media (images, videos, etc...)

3.png

Create a Next.js Project

Open your terminal and create a new Next.js project using the following command:

npx create-next-app@latest

Install BCMS Packages

Run the following command to install BCMS-related packages:

npm i --save @thebcms/cli @thebcms/client @thebcms/components-react

Update package.json

Modify the scripts section in package.json as follows:

"scripts": {
  "dev": "bcms --pull types --lng ts && next dev",
  "build": "bcms --pull types --lng ts && next build",
  "start": "bcms --pull types --lng ts && next start",
  "lint": "bcms --pull types --lng ts && next lint"
}

The bcms --pull types --lng ts command starts the BCMS CLI and pulls types from BCMS, saving them in /bcms/types/. These types work for both JavaScript and TypeScript.

Update TypeScript Configuration

If you’re using TypeScript, open tsconfig.json and set moduleResolution to Node:

{
   "compilerOptions":{
      "lib":[
         "dom",
         "dom.iterable",
         "esnext"
      ],
      "allowJs":true,
      "skipLibCheck":true,
      "strict":true,
      "noEmit":true,
      "esModuleInterop":true,
      "module":"esnext",
      "moduleResolution":"Node",
      "resolveJsonModule":true,
      "isolatedModules":true,
      "jsx":"preserve",
      "incremental":true,
      "plugins":[
         {
            "name":"next"
         }
      ],
      "paths":{
         "@/*":[
            "./src/*"
         ]
      }
   },
   "include":[
      "next-env.d.ts",
      "**/*.ts",
      "**/*.tsx",
      ".next/types/**/*.ts"
   ],
   "exclude":[
      "node_modules"
   ]
}

Initialize BCMS Client

In the /src directory, create a new file called bcms.ts. Inside, initialize the BCMS client:

import { Client } from '@thebcms/client';

export const bcmsPrivate = new Client({ injectSvg: true }); // by default, apiKey is set to use BCMS_API_KEY

export const bcmsPublic = new Client({
    apiKey: process.env.NEXT_PUBLIC_BCMS_API_KEY,
    injectSvg: true,
});

Env file

In the .env file, place this:

BCMS_API_KEY=<YOUR.API.KEY>
NEXT_PUBLIC_BCMS_API_KEY=<YOUR.PUBLIC.API.KEY>

Fetch and Display Data

In /src/app/page.tsx, fetch data from the BCMS project and display it on the page:

import { bcmsPrivate } from "@/bcms";
import { BlogEntry } from "../../bcms/types/ts";
import { BCMSContentManager, BCMSImage } from "@thebcms/components-react";
export default async function Home() {
  const blogs = (await bcms.entry.getAll("blog")) as BlogEntry[];
  return (
    <main>
      <div className="flex flex-col gap-4">
        {blogs.map((blog, blogIdx) => {
          if (!blog.meta.en || !blog.content.en) {
            return "";
          }
          return (
            <div key={blogIdx} className="flex flex-col gap-8">
              <h1 className="mb-10 text-3xl">{blog.meta.en.title}</h1>
              <BCMSImage
                className="w-full h-60 object-cover"
                media={blog.meta.en.cover_image}
                clientConfig={bcms.getConfig()}
              />
              <BCMSContentManager items={blog.content.en} />
            </div>
          );
        })}
      </div>
    </main>
  );
}

That's it — happy coding!