Why BCMS is the Best CMS for NextJS: 6 Less Obvious Reasons
5 Feb 2024
This Gatsby vs Next vs Nuxt article is written to collect all the facts, trends, and insights about the top 3 of the most popular JavaScript frameworks and examine them.
Before comparison, let's go through a quick scan of all 3 frameworks.
Gatsby is a static site generator that uses React to build websites. Utilizing GraphQL, Gatsby provides a rich development experience that allows data to be queried from APIs, databases, and files.
Gatsby is suitable for building:
Blogs
Portfolios
E-commerce
Next.js is a framework for building server-rendered React websites and applications. It provides out-of-the-box server-side rendering, code splitting, and static export support. The Next.js framework also supports static site generation and API routes, making it extremely versatile.
Next.js is suitable for building:
e-commerce websites
serverless applications
complex web apps
Nuxt.js is a Vue.js-based framework for building server-rendered applications. Nuxt provides out-of-the-box server-side rendering, code splitting, and static export support. Nuxt.js is also known for its robust plugin system that allows developers to extend the framework's functionality quickly.
Nuxt.js is suitable for building:
e-commerce websites
Blogs
enterprise apps
This comparison will focus on several key factors for each framework. From current trends in the industry through key features and differences, all to get the ultimate insights into all frameworks and their cons and pros.
NPM Trends is very useful when comparing the download rates of different packages. So, let's see what statistics say about our 3 frameworks.
This picture shows downloads yearly, but here are more up-to-date numbers ( December 2023)
Looking at these trends, you could conclude that Next.js is the most popular (and therefore the best) framework of the three we are comparing. And is it so?
I would say no. Why? Because each framework has pros and cons, and depending on the project's needs, sometimes the best solution will be the one that is not the most popular regarding trends.
So, let's leave trends and check out some other parameters. Key features, for example? 🤔
Gatsby builds user interfaces with React.js and its component-based methodology, resulting in seamless integration.
Gatsby prioritizes performance through code splitting, image optimization, and lazy loading, resulting in fast websites with an excellent user experience.
Gatsby uses GraphQL to efficiently retrieve and handle data from various sources such as APIs, databases, and markdown files, streamlining data retrieval and manipulation.
Gatsby's extensive plugin ecosystem makes it simple for developers to extend the framework's capabilities. Plugins offer flexibility for enhancing SEO features or connecting with external services.
Gatsby enables the creation of PWA, ensuring dependable, quick, and captivating websites regardless of network conditions.
The most famous Next.js feature is strong server-side rendering support, which leads to quicker page loading times and enhanced SEO. Thanks to this approach, users get better UX.
Static Site Generation enables Next.js developers to pre-render complete pages during the build process, which leads to high-speed loading. Furthermore, SSG can be blended with client-side rendering to handle dynamic components.
Next.js provides an easy-to-use routing system that includes built-in dynamic routing. Parameterized routing and nested routing add flexibility to an application or website design.
Next.js offers smooth incorporation of TypeScript and CSS-in-JS. This gives developers strong type-checking and styling abilities, ultimately leading to manageable, error-free codebases.
Next.js includes an integrated API routing system, enabling developers to build serverless functions to manage API requests that streamline backend development.
As a Vue-based framework, Nuxt.js effortlessly integrates Vue's dynamic data binding and modular component structure.
Like Next.js, Nuxt.js offers SSR and SSG features, improving speed and SEO benefits.
Automatic routing boosts code organization and speeds up development.
Nuxt.js combines with Vuex, enabling centralized state management for more straightforward handling and data sharing across components.
Middleware empowers developers to create functions that execute before pages or layouts are rendered. You can use this for authentication, authorization, and data fetching.
All three frameworks have features and functionalities to help developers create any site or application.
However, the nuances are what can influence the final decision. Instead of focusing on which framework is the best, I decided to focus on their differences (which I think will be more beneficial for you to choose a framework).
Also, I will use a comparative analysis so that developers can understand which tool helps them with the project based on specific parameters.
Developers use libraries to leverage these pre-built code snippets to perform everyday tasks without reinventing the wheel. So, having a detailed list of requirements will help you narrow your options and focus on the ones that match your criteria.
Regarding libraries:
React is the core of Gatsby, which takes advantage of the component-based architecture of React.js.
Next.js is a React framework that enables several extra features, including server-side rendering and generating static websites.
Based on the Vue.js ecosystem and syntax, Nuxt.js is designed specifically with Vue.js applications in mind.
If we are going to generalize, all websites work the same. The client sends the server an initial request containing the desired information. The server returns the requested file, which may or may not result in a cascade of additional requests. Finally, the client has all the necessary data and can render a page to display the information to the user visually.
HTML and CSS files are stored on the server and delivered to the client upon request for static content, which is content that looks the same for every user and does not require any computations. Unfortunately, much of the web is made up of dynamic content that must change for each user, possibly even depending on the time or state in which the user accesses the web resource. For those reasons, there are many different rendering modes and strategies.
Regarding rendering modes:
To optimize performance, Gatsby prioritizes static site generation.
Performance and SEO are at the forefront of Next.js, with support for SSR and SSG.
The rendering modes available in Nuxt.js can be adjusted to suit the needs of each project.
File-based routing is a method used by certain web development frameworks or platforms to handle page generation by simply organizing folders and files, usually inside of the pages
folder.
Regarding routing:
With Gatsby, you can control URL patterns and page generation more finely through its configuration files. (Programmable routing)
I will use BCMS' Gatsby Blog Starter as an example to explain Gatsby routes:
As you can see in the picture, there is the pages
folder and .tsx
files inside, where each file represent a page. Simply right?
But, for dynamic blog pages, Gatsby requests templates/blog.tsx
file to make it possible to generate dynamic blog pages. How to generate dynamic blog pages? Follow the next steps:
To generate dynamic blog pages, you must also have gatsby-node.ts
file with the following code:
import { NodePluginArgs } from 'gatsby'; import { BlogEntry } from './bcms/types'; import { getBcmsMost } from 'gatsby-source-bcms'; import path from 'path'; exports.createPages = async ({ actions }: NodePluginArgs) => { const { createPage } = actions; // SINGLE BLOG PAGES const blogTemplate = path.resolve('./src/templates/blog.tsx'); const bcms = getBcmsMost(); const blogs = (await bcms.content.entry.find( 'blog', async () => true, )) as BlogEntry[]; if (blogs.length > 0) { blogs.forEach((blog) => { createPage({ path: `/blog/${blog.meta.en?.slug}`, component: blogTemplate, context: { id: blog._id, }, }); }); } // END OF SINGLE BLOG PAGES };
In this code, you mainly get all the blogs from the CMS, and based on their slugs, you can generate pages for each blog on the path /blog/slug-blog. To do so, use this piece of code:
createPage({ path: `/blog/${blog.meta.en?.slug}`, component: blogTemplate, context: { id: blog._id, }, });
Next.js and Nuxt generate pages according to the same principle.
Routes are generated automatically based on the file structure of the directory holding the pages. This reduces the need for explicit route definitions in the configuration file.
Let's keep using BCMS Blog Starters as an example (This time Nuxt Blog Starter). From the pictures above, you can see that Next.js and Nuxt generate pages based on folder and file structure: pages/about-me.vue
means that the page will be generated at /about-me
pages/contact.vue
means that the page will be generated at /contact
And as for the dynamic blogs routes, there you have to 'catch' all possible options for the slug, so you can't make fixed pages/blog/why-is-bcms-best.vue
, but pages/blog/[slug].vue
, where that [slug] will be a dynamic part, and it can catch all possible slugs ( /why-is-bcms-best, /how-is-this, /why-is-that, etc.)
Next.js works precisely the same, but only there are files with .tsx,
not.vue,
because it is a React-based framework.
In this section, spending as few words as possible and more examples is better.
Gatsby has an opinionated setup process that provides various performance optimizations and defaults out of the box. Gatsby uses the gatsby-config.ts file
. Example for the blog starter:
import * as dotenv from 'dotenv'; import { createBcmsMostConfig } from '@becomes/cms-most'; import type { GatsbyConfig } from 'gatsby'; dotenv.config({ path: `.env.${process.env.NODE_ENV}`, }); const config: GatsbyConfig = { siteMetadata: { title: 'cms-gatsby-starter', siteUrl: 'https://www.yourdomain.tld', }, plugins: [ 'gatsby-plugin-sass', 'gatsby-plugin-sitemap', { resolve: 'gatsby-plugin-manifest', options: { icon: 'src/images/icon.png', }, }, { resolve: 'gatsby-source-bcms', options: createBcmsMostConfig({ cms: { origin: process.env.BCMS_API_ORIGIN || 'http://localhost:8080', key: { id: process.env.BCMS_API_KEY || '6433b6994c02e25452a8a947', secret: process.env.BCMS_API_SECRET || '4107ecd203ff708a1789439376934e315781d66134d6c0da058bc87583f6e0c9', }, }, media: { download: true, output: 'static/api', images: { process: true, }, }, server: { port: 3001, }, }) as any, }, ], }; export default config;
Here's more info about Gatsby configuration.
Next.js provides a minimalistic setup with easy-to-understand configuration options. Next.js uses thenext.config.js
file. Example for the blog starter:
const { createBcmsNextPlugin } = require('next-plugin-bcms/main'); createBcmsNextPlugin(); /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, i18n: { locales: ['en'], defaultLocale: 'en', }, }; module.exports = nextConfig;
Here's more info about the Next.js configuration.
Nuxt follows a convention-over-configuration approach, automating many setup steps and allowing configuration customization. Nuxt uses the nuxt.config.ts
file, where everything is handled. Example for the blog starter:
import { createBcmsNuxtConfig } from 'nuxt-plugin-bcms/config'; // eslint-disable-next-line @typescript-eslint/no-var-requires const _ = require('lodash'); const svgPrefix = {}; svgPrefix.toString = () => `${_.uniqueId()}_`; // https://nuxt.com/docs/api/configuration/nuxt-config export default defineNuxtConfig({ vite: { optimizeDeps: { include: ['axios', '@becomes/cms-client'], }, }, runtimeConfig: { public: { bcmsApiOrigin: '', bcmsApiKeyId: '', bcmsApiKeySecret: '', bcmsEnableClientCache: '', bcmsClientDebug: '', bcmsEntryStatuses: '', bcmsMostServerPort: '', bcmsMostServerDomain: '', }, }, app: { head: { titleTemplate: '%s - Insightful Ink', link: [ { rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png', }, { rel: 'icon', type: 'image/png', sizes: '32x32', href: '/favicon-32x32.png', }, { rel: 'icon', type: 'image/png', sizes: '16x16', href: '/favicon-16x16.png', }, { rel: 'manifest', href: '/site.webmanifest' }, { rel: 'mask-icon', href: '/safari-pinned-tab.svg', color: '#5bbad5' }, ], meta: [ { name: 'msapplication-TileColor', content: '#da532c' }, { name: 'theme-color', content: '#ffffff' }, { property: 'og:type', content: 'website' }, { property: 'twitter:card', content: 'summary_large_image' }, ], }, }, css: [ '~/assets/css/fonts.css', '~/assets/css/main.css', '~/assets/css/reset.css', '~/assets/css/transition.css', '~/assets/css/prose.css', ], modules: [ 'nuxt-svgo', [ 'nuxt-plugin-bcms', createBcmsNuxtConfig({ cms: { origin: process.env.BCMS_API_ORIGIN || 'http://localhost:8080', key: { id: process.env.BCMS_API_KEY || '6433b6994c02e25452a8a947', secret: process.env.BCMS_API_SECRET || '4107ecd203ff708a1789439376934e315781d66134d6c0da058bc87583f6e0c9', }, }, websiteDomain: 'http://localhost:3000', postProcessImages: true, media: { download: true, images: { process: true, }, }, }), ], ], svgo: { svgoConfig: { plugins: [ { name: 'preset-default', // params: { // overrides: { // cleanupIDs: { prefix: svgPrefix }, // }, // }, }, ], }, }, postcss: { plugins: { tailwindcss: {}, autoprefixer: {}, }, }, });
Here's more info about the Nuxt configuration.
Fetching is the process of grabbing data from the database and making it available to the application.
From this, it's evident that data fetching is a fundamental concept in building modern front-end websites and applications. It allows applications to retrieve data from the backend and present it to users, achieving interactive, real-time, and rich user experiences.
Regarding data fetching:
Gatsby uses GraphQL during the build process to fetch data, pre-render pages with the fetched data, and improve performance by reducing the need for client-side data fetching.
Next.js and Nuxt support server-side data fetching, allowing developers to fetch data while server-side rendering for better SEO and initial load times.
The development approach may be one of the most important metrics in choosing a tool to build websites and apps.
Gatsby emphasizes performance and static site generation, creating highly optimized websites that load quickly and provide excellent SEO benefits.
Next.js balances server-side rendering and client-side interactivity, making it suitable for projects where both aspects are important.
Nuxt prioritizes server-side rendering and seamless Vue.js integration, delivering a smooth user experience with pre-rendered content.
Since there are 3 frameworks, there are 3 essential questions that will sum up this whole article and help you choose your framework.
Do you want to build a full-stack app or not?
If so, do you want more freedom and flexibility or prefer out-of-the-box modules, if available in the first place, that you can plug in to get the desired result?
If the app doesn't require full-stack development, which rendering strategy, do you prefer based on your needs for performance and SEO-friendliness?
After answering those 3 questions, you will know how to make the right choice. One thing left?
Install BCMS, choose the winner in this "Gatsby vs Next vs Nuxt" battle, and start building modern websites and apps.
Get all the latest BCMS updates, news and events.
By submitting this form you consent to us emailing you occasionally about our products and services. You can unsubscribe from emails at any time, and we will never pass your email to third parties.
There are many actionable insights in this blog post. Learn more: