Next.js In Review: An Exceptional Experience for Developers Building on a Headless CMS
Mike Vertal
Facebook's React UI framework, introduced in 2013, has been a trailblazer in the frontend world since its introduction. Developing dynamic websites with rich functionality was hard back then, and many devs (and upper management) considered Javascript a toy language: useful for adding a little extra functionality like input validation to a site, but something web offerings had to be able to function without. "Progressive enhancement" gave a name to this practice. React, and later frameworks that tailored it to specific use cases, changed that.
CrafterCMS is an open source headless CMS designed to provide an enterprise-class solution for a wide variety of digital experience applications. Next.js is a strong contender for building out your next enterprise website, digital product, customer portal, or any other type of digital experience. But first, let's consider what problems Next.js is seeking to solve.
A Developer's View of React.js
The challenge for any framework author is finding the right mix of opinions to enforce vs. providing the flexibility developers need to exceed client and user expectations. In contrast to other popular frontend libraries, React took a UNIX-like approach. It focuses on a narrow slice of the web app pie and provides a Javascript-based view templating library with a syntax that is comfortable for developers familiar with HTML, called JSX. React's architecture naturally leads developers to break a project up into the various components that compose web pages, and keeps the pieces that used to be scattered across multiple code files in single files - layout markup, stylings, and logic.
Like most UNIX utilities, React solves the problem it's designed to address very well. It introduced the idea of a virtual DOM to aggregate changes to a browser's document model, and push multiple changes at once to improve performance. It enforced a one-way data flow that simplified the headaches of reasoning about state held in the real DOM and that can be mutated by anything, seen or unseen. But the downside of React, as with UNIX utilities, is that the burden of building a full pipeline to do meaningful work is on the shoulders of developers.
Building those pipelines with React was often so bad that it led to a new term being coined in the industry - "Javascript Fatigue", with some even suggesting it was a genuine clinical condition that mental health professionals could treat. The fatigue wasn't just about React, of course, but working with un-opinionated frontend view libraries contributed heavily to the phenomenon; Vue was also gaining momentum at the time, and was based on React. Setting up language transformers, complex build pipelines, and piecing together libraries to build full frontend apps was real work and time-consuming.
Next.js to the Rescue
Facebook's React team recognized the problems developers were having and introduced the create-react-app app (so meta) to help. CRA provided some elementary opinions on project structure and a preconfigured build pipeline. It bundled the configuration into NPM modules, so that a project could stay current with the project and avoid managing dependencies themselves, and an option to "eject" and copy all configuration into your project repo if your needs varied. A whole ecosystem of "create-" style apps sprung up based on CRA that offered more opinionated approaches and to save dev time - including a preconfigured Apollo client for state management and GraphQL API tooling.
Next.js has its roots in the CRA ecosystem of downstream apps that expand the footprint of Facebook's original CRA. One problem "create-" style apps introduce is there's now a lot of abandonware out there. While vendor provided extensions to CRA are usually well maintained, they're also usually limited in what they add. Developers using "create-" style apps that match closely with what they need often face the choice of either ejecting and assuming responsibility for dependency management, or falling behind and being barraged with security vulnerability reports in their CI pipelines.
Next.js is a site generator built on React , and introduces well-considered patterns to building out your frontend. It's a stand-alone application that's intended to be included into your project as a module, not a "create-" app that you eject from. In fact, Vercel (formerly Zeit, and Next's maintainer) offers their own create-next-app that's actually a scaffold generator to create a quick-start project template for you. The tool also lets you use Next-specific CRA-style projects as a template for additional preconfigured functionality.
What Exactly is a Site Generator?
CRAs are designed for client-side rendering. The index.html page delivered to a browser on page load usually has a sparse body: generally the body of the document contains a single, empty tag with an id set. Once the browser has loaded and begins executing the client code bundle, React will reference the empty tag and inject the page's HTML dynamically in place of the marker tag. From that point on, everything happens in code: when a user navigates to a new page, React intercepts the link and generally fetches the data to build the next page using an API.
Next.js pulls some features from client-side rendering CRAs that developers love: hot module reloading, so that changes in code are reloaded in the browser immediately, and a preconfigured build pipeline with tree-shaking to minimize the size of code bundles delivered over the wire to browsers. But Next's execution model is fundamentally different, at least for the first page load.
Next.js works by generating static HTML files to deliver to the browser that are fully populated with the page content and markup. The page will render, even with Javascript turned off - an important feature for search engine robots, given the intricacies of how they handle scripts as they scrape the web. Next.js can generate all pages on a site statically when content changes (via static site generation or SSG) or generate them individually as they are requested by users (via server-side rendering or SSR). Dynamic content, like user avatars, can still be rendered client-side. Next.js supports client-side React hydration in SSG and SSR modes, where the HTML is annotated and, after rendering, React is initialized and assumes control in the browser.
Next.js Features
Routing: Next.js is opinionated on routing and offers a file-based routing system and mandatory file hierarchy that developers need to maintain in a project. It provides dynamic routing, where the build system applies a given page template to all content from an API endpoint that returns a list, such as CrafterCMS's organization of content into a site navigation tree. Next's routing solution also offers prefetching, where likely links that a user might click are loaded in the browser before the user navigates to them.
React Hooks for SSG and SSR: Next.js provides simple hooks to include in pages that are generated using SSG and SSR strategies. Pages can also be delivered for client-side rendering, as with vanilla CRAs.
Styling Support: Next.js offers built-in support for using external style sheets, with or without a preprocessor like SCSS, and also CSS-in-JS solutions like Emotion.
Advanced Code Splitting: Next.js is a great platform to build on for achieving high Google Lighthouse performance metrics, boosting your site's potential SERP placement. You can deliver just the code bundles a given page needs and avoid loading large and mostly-unused code to users.
Lambda Support: Next.js makes working with serverless functions easy. Hosting providers like Netlify and Vercel are integrated with Next to automatically deploy lambdas, and Next provides support for hosting lambdas - especially useful in developer environments.
Combining CrafterCMS and Next.js
CrafterCMS is always on the lookout for the latest technologies to help our community innovate. That means offering as many points of integration and approaches as possible so that organizations can bring the best tools available into their tech stack.
Next.js is a solid option for organizations needing to develop and deploy web offerings quickly, while still offering a full-featured platform to build out complex apps. CrafterCMS is an enterprise-class, Git-based headless CMS that provides an API-first content repository with a wide variety of APIs (REST, GraphQL, Javascript, Groovy/Java, Freemarker), workflow tools, and full-featured administrative UI for content authors and editors, and is a great backend choice to pair with Next.js.
Learn more about CrafterCMS’s Javascript SDK here. You may also freely download the latest version of the open source CrafterCMS project here.
Related Posts
Dynamic Content Delivery at Scale with a Decoupled CMS
Amanda Lee
Headless CMS Use Case: Intranet
Sara Williams
What's New in CrafterCMS v4.2: Enhanced Studio UX, OpenAI Integration, and More
Russ Danner
What Is HTMX?
Amanda Jones