Getting started with the dotCMS Universal Visual Editor with Next.js

Preston So

One of dotCMS’s key features is a Universal Visual Editor that enables developers and content editors alike with a framework-agnostic visual building interface. You can use the Universal Visual Editor to power both hybrid-headless architectures (with dotCMS’s native template language Velocity) and headless or decoupled architectures delivering content to JavaScript or other presentation layers.

The Universal Visual Editor from dotCMS is a core tenet of the universal content management system, a rapidly growing approach for content management systems (CMSs) that allows both content and developer teams to innovate unimpeded, irrespective of the framework or channel leveraged to present their content. The universal CMS is a new stage of the development of the CMS that privileges both content and developer functions as first-class citizens across all web-renderable delivery channels.

At present, Next.js is widely used as a JavaScript framework enabling React developers to craft statically generated or server-rendered websites. Via the dotCMS SDK ecosystem, developers can integrate seamlessly between their in-progress Next.js apps that consume information from dotCMS and editorial interfaces in dotCMS that permit editors to build and manage content visually as component-level blocks.

In this blog post, I’ll demonstrate how you can get started with the Universal Visual Editor and Next.js in just fifteen minutes. As we get started, check to see that you have the Docker command-line interface (CLI) installed on your machine, as well as key tools like NPM, Node.js, a code editor, and a terminal. By the way, if you’re using Docker Desktop, you already have the Docker CLI available on your system!

Instantiate dotCMS in a single command

Let’s get going! In order to set up a running dotCMS back-end instance that makes example content available, as seen in the dotCMS Next.js example, we’ll need to create an instance. Run this single command to spin up a new dotCMS instance based on the latest nightly build:

docker run --rm \

--pull always \

-p 8082:8082 \

-p 8443:8443 \

-v $PWD/data:/data \




This command creates a Docker container that’s based on the dotCMS demo environment, located at, retrieves the data used in the instance, and makes all of this available at the localhost port 8082 (no HTTPS) and port 8443 (with HTTPS).


The outcome of running docker run and spinning up a local dotCMS instance.

Head over to http://localhost:8082 in your browser, and you’ll see your local dotCMS instance running. It shows the default demo data that accompanies the dotCMS demo instance.


Our just-created local dotCMS instance’s home page, displaying prepopulated demo content.

Now, we can head over to http://localhost:8082/dotAdmin to access the dotCMS interface. Log in using the user name and password admin.


The sign-in modal for the back-end interface of the locally running dotCMS instance.

To use Universal Visual Editor with Next.js, you’ll need an enterprise license from dotCMS for the remainder of this tutorial. Need one? Get in touch with the dotCMS sales team or leverage the example instance that’s publicly available to retrieve your content for Next.js, which can be found at with the same user name and password as seen above. For security reasons, the public dotCMS demo instance is restored to a default state every 24 hours.

You can add a license into your local instance by heading over to Settings > Configuration and clicking on the Licensing tab. There, you can provision a license by hitting the Upload License Pack button.


The currently applied license, viewable on the dotCMS Licensing configuration page.

As a last step before we proceed, you’ll need to provision an API access token such that the Next.js app we’re building can retrieve dotCMS content. This ensures that our Universal Visual Editor interface functions as designed and avoids any access issues down the road. Head over to Settings > Users, choose the root user (“Admin User”), and switch over to the API Access Tokens tab. Add a JSON web token (JWT) for use in our Next.js app. In the screenshot below, you can see a newly created JWT with the label “UVE Next.js.”


To consume dotCMS data, our Next.js app needs an API access token, created here.

Nice one! Now, our local instance is prepared to deliver content to Next.js.

Generating a dotCMS Next.js example app

We can now generate a new Next.js app against the official dotCMS Next.js example repository by running the following in our terminal, within a folder where the code should be found. Here, I’ve given the newly created Next.js app the name dotcms-uve-nextjs:

npx create-next-app dotcms-uve-nextjs --example

As an alternative, you can also directly clone the Next.js example without employing the create-next-app generator. Or, you can also directly utilize the Next.js app that’s located within a cloned monorepo of dotCMS core on your machine. While this is fantastic for quick hacking and demoing, it’s not the best idea for use in production environments.

Cool! Our Next.js app is now prefabricated and ready to integrate with our dotCMS instance.

Configuring the Next.js example for dotCMS

Our next step is to add some configuration to the Next.js app code to indicate which dotCMS instance it should acquire content from in order to build its routes and components.

As an initial step, get the Next.js app open in your code editor (for example, by running code . in the dotcms-uve-nextjs folder). Then, rename the environment variables file so our local development environment can use it by changing the name of .env.local.example to .env.local. Now, edit the following variables located in the file:

  • DOTCMS_AUTH_TOKEN: This environment variable contains the JWT that represents your local dotCMS instance credentials. You can find these by heading to Settings > Users, navigating to “Admin User,” and hitting “get token” in the table row where your JWT was created, as you can see in the following screenshot.


The JSON web token (JWT) we generated as seen within the dotCMS administrative interface’s API access tokens screen.

  • NEXT_PUBLIC_DOTCMS_HOST: This environment variable represents the instance URL, here http://localhost:8082.

In the following screenshot, you can see how your environment variables should look in the .env.local file. Both DOTCMS_AUTH_TOKEN and NEXT_PUBLIC_DOTCMS_HOST are filled in with values.


The .env.local file now houses the two just-mentioned environment variables.

Hooray! We’ve just configured the information Next.js needs so it can get the content it needs from the dotCMS instance.

Locally running the dotCMS Next.js example

Next, we can spin up a local development environment for our dotCMS Next.js example so we can view it in a browser. By the way, the Next.js app uses @dotcms/client to access dotCMS data and @dotcms/react to build out the pages and components Next.js needs. Head back to the root folder of your Next.js app (such as dotcms-uve-nextjs) and run this command:

npm run dev

Within your terminal, you’ll see what’s shown in the following screenshot. Open your browser and head to http://localhost:3000, where you’ll see the Next.js example app running.


The output of the npm run dev command as it spins up a local development environment for Next.js.

As a note, our dotCMS Next.js example app  (localhost:3000) leverages a headless (or decoupled) architectural approach, delivering the same exact copy we viewed within the monolithic dotCMS demo instance (localhost:8082). The dotCMS Universal Visual Editor is capable of enabling editors across both types of architectures, which is an important facet of the universal CMS paradigm.

Great! Next, we can detect the Next.js application in dotCMS and view and update the content in our site within the Universal Visual Editor. Let’s do it!

Modifying dotCMS content using the Universal Visual Editor

The next step is to configure the Universal Visual Editor integration app, viewable in the local instance, such that the Universal Visual Editor in dotCMS can detect the Next.js app. Head over to Settings > Apps and click on “UVE - Universal Visual Editor” in your dotCMS instance:


The “UVE - Universal Visual Editor” integration in the Apps page as seen in the dotCMS interface.

Then, click the plus button at the right of, which represents our local docker-created dotCMS demo instance:


The configuration screen in the “UVE - Universal Visual Editor” interface.

Insert the JSON object below into the Configuration field, which expresses the URL for the Next.js app we’re serving data to:

{ "config":



      "pattern": ".*",

      "url": "http://localhost:3000",




This JSON object includes a regular expression (RegEx) in the pattern key, indicating which URLs are connected with the Next.js app for dotCMS. Spoiler alert: there’s more you can do here (more later)! Meanwhile, the url key defines the root URL where the Next.js app can be found.


The Next.js app’s JSON configuration object as displayed within the “UVE - Universal Visual Editor” configuration screen within the dotCMS interface.

Next, you can click Save and head to Content > Pages. We can then edit the “Home” dotCMS page by hitting “Home” in the content listing.


The “Home” content item as shown in the content listing interface within the dotCMS instance.

To modify the text contained within the hero component, click the pencil button in the corner of the hero component:


The Next.js app shown presenting the “Home” content item data within the Universal Visual Editor.

As a next step, we can update some of the header text. In this context, we’ve modified the text “Explore the World” to “Explore the Universal CMS.”


The header component’s edit modal for the Next.js-consumed “Home” content item.

Once you click the Publish button and exit out of the edit modal, you’ll be able to see the modified text updated in the Universal Visual Editor interface …


The updated header text as shown in the Next.js component within the Universal Visual Editor.

… and in our local Next.js development environment at localhost:3000, you can see it updated too!


The edited text in dotCMS as displayed in the newly updated Next.js app.

Amazing! In less than fifteen minutes, you’ve set up the dotCMS Universal Visual Editor, along with headless visual editing capabilities and a Next.js development environment. Now that we’ve got it all running, you can innovate as desired if you’re a developer in Next.js, and you can edit both content and visual presentation of Next.js components if you’re an editor—all using the shared Universal Visual Editor interface.

Conclusion and next steps

The next phase of the CMS, as hybrid-headless and headless market players engage in convergent evolution, is the universal CMS. For our vision for this new paradigm at dotCMS, the Universal Visual Editor is a foundational element. Just in case you’re interested in doing even more past the end of this tutorial, you can edit the JSON object found in the “UVE - Universal Visual Editor” configuration screen in your dotCMS site to define URL sets within your instance to allocate specific editorial interfaces.

As an illustrative example, let’s suppose you have a dotCMS site that delivers data to a storefront implemented in Vue.js (for instance at localhost:8000) and to a blog implemented in Next.js (for instance at localhost:3000). Using RegEx, you can designate URL patterns to allow editors to edit content and how it appears in both the Next.js and Vue.js apps differentially, as seen below:

{ "config":



      "pattern": "./storefront/*",

      "url": "http://localhost:8000",



      "pattern": "./blog/*",

      "url": "http://localhost:3000",




In the universal CMS paradigm, a key piece of functionality is the ability to edit universally across any framework in JavaScript agnostically, be it Vue.js, Next.js, or another tool. Lots more to come on the Universal Visual Editor soon! Meanwhile, read more about why the universal CMS is the future of content management writ large.

Preston So
Vice President of Product
May 29, 2024

Recommended Reading

Beware of CMS Fads

This blog warns against adopting new technologies without sufficient consideration, using examples to illustrate how jumping on trends can lead to wasted resources.

24.04.24 LTS: Upgrade to the Universe

Now available: dotCMS 24.04.24 LTS, the first long-term supported release of 2024