How to connect BCMSΒ and NextJS

By Branislav Vajagić
Read time 2 min
Posted on October 13, 2022
Updated on June 13, 2023
Share it on:
BCMS  and NextJS

Requirements

Creating a Next.js project with BCMS

In this tutorial, we will use local BCMS with default data to make it easy for you to follow.

We will create a NextJS project using the BCMS CLI by running bcms --website create. After running the command, you will be prompted to decide on a few options:

  • For the project name, you can enter anything; we will leave it as default.

  • When asked to select a framework, select Next.

  • When you asked if you want to connect to the BCMS, answer with y (yes). After this, you will be asked which type of BCMS you wish to connect to. Since we are using local BCMS, we will select locale, but if you are using the live version, then select Live.

  • Since our NextJS project needs an API key to be able to access the data from the BCMS, in the next step, we will need to select an API key that we would like to use. If in your BCMS you do not have any API keys, CLI will automatically create one, but if that is not the case, you will be asked to select an available API key or create a new one.

BCMS CLI steps for creating NextJS website.
Figure 1 - BCMS CLI steps for creating NextJS website.

After completing all the above steps, the CLI will initialize the project and install dependencies. The process is done, you can open the project in your favorite code editor (I will use VSCode) and run npm run dev. Now you can open the browser and navigate to http://localhost:3000.

Project structure

As you can see, this is a typical NextJS project, but you might spot a few unusual files and folders. Let's see what those files are and what they are used for.

  • ./bcms.config.js - This file is used to configure the BCMS Most, which is an API layer between the BCMS and your project. For short, the Most makes it easy to get data from the BCMS and synchronize it in real time.

  • ./bcms.routes.js - To define custom API routes of the Most server (by default running on localhost:3001). This is an advanced feature, and we will cover it later in more detail.

  • ./bcms - This is a dynamic directory created by the Most, and it is used for caching data and storing data types from the BCMS. Yes, If you are using TypeScript, GraphQL, or even JSDoc, we got you covered!

That's all the stuff related to the BCMS. Everything else is the vanilla Next.js.

Where to deploy?

You can deploy your NextJS application powered by the BCMS anywhere you would be able to deploy any other NextJS application. Just keep in mind that you won't benefit from BCMS Cache if you are deploying your app on a platform that uses serverless technology.

We use and recommend the following platforms:

How to get data on the page?

There are 2 ways you can get data from the BCMS and display it on the page.

Using the BCMS Client, and the other is using BCMS Most. The best way to explain this is to show you an example. Let's say that we have Blog entries in our BCMS, and we want to display one blog post on the path /blog/{blog-slug}.

With BCMS Client, you can do something like this:

import { GetServerSideProps } from 'next';
import { getBcmsClient } from 'next-plugin-bcms';
import React, { FC } from 'react';
import { BlogsEntry } from '../../bcms/types';

interface Props {
  blog: BlogsEntry;
}

export const getServerSideProps: GetServerSideProps = async () => {
  const client = getBcmsClient();
  const blog: BlogsEntry = await client.entry.get({
    template: 'blogs',
    entry: 'my-first-blog',
  });
  return {
    props: {
      blog,
    } as Props,
  };
};

const Blog: FC<Props> = (props) => {
  return (
    <pre style={{ fontFamily: 'monospace' }}>
      {JSON.stringify(props.blog, null, '  ')}
    </pre>
  );
};

export default Blog;
          

and with BCMS Most you can do something like this:

import { GetServerSideProps } from 'next';
import { getBcmsMost } from 'next-plugin-bcms';
import React, { FC } from 'react';
import { BlogsEntry } from '../../bcms/types';

interface Props {
  blog: BlogsEntry;
}

export const getServerSideProps: GetServerSideProps = async () => {
  const most = getBcmsMost();
  const blog: BlogsEntry | null = await most.content.entry.findOne(
    'blogs',
    async (e) => e.meta.en.slug === 'my-first-blog',
  );
  if (!blog) {
    return {
      notFound: true,
    };
  }
  return {
    props: {
      blog,
    } as Props,
  };
};

const Blog: FC<Props> = (props) => {
  return (
    <pre style={{ fontFamily: 'monospace' }}>
      {JSON.stringify(props.blog, null, '  ')}
    </pre>
  );
};

export default Blog;
          

What is the difference between getting data using BCMS Most and BCMS Client?

The simple answer is that BCMS Client will make an API request to the BCMS every time, while BCMS Most will check the local cache and decide if an API request is needed.

There are more details to this answer but simply put, for now: if you want to deploy your application to Vercel or Netlify, you should use BCMS Client, and if you are deploying to Railway or DigitalOcean App Platform, you should use BCMS Most.

BCMS Image - to the rescue!

Let's face it, we all love images on the web. High-quality, sharp ones. But we also love fast websites. Why can't we have both? Well, BCMS Image lets you have both. To simplify handling responsive images and performance optimization, we created the BCMSImage component.

If you are using the CMS with the demo dataset (which is available if you are running the BCMS locally), there blogs have a cover_image property. To start, import the BCMSImage component, add it to the render and pass the cover_image object.

return (
  <div>
    {props.entry.meta.en?.cover_image && (
      <BCMSImage media={props.entry.meta.en.cover_image} />
    )}
    <pre>
      <code>{JSON.stringify(props.entry, null, '  ')}</code>
    </pre>
  </div>
);
          
BCMSImage with no options.
Figure 2 - BCMSImage with no options.

If you resize your browser, you'll see that the image size is changing. It's not some CSS magic, but the real image source is changing. If you inspect the image, you'll see that the image source is the same size as it appears on the screen.

Taraaam. You have your blog set up! Congrats! πŸŽ‰

Where to go next