Build your own CMS using low-code
Shubhendra Singh Chauhan
Posted on March 28, 2023
In this tutorial, We will build CMS(Content Management System) using the ToolJet which is a lowcode application development platform. The CMS can be used to perform CRUD operations to the MongoDB which is used as the database for the NextJS application.
Table of Contents
- Overview
- Prerequisites
- Setting up the database
- Connecting MongoDB to ToolJet
- Building the UI, Queries and connecting them
- Connecting to NextJS app
Overview
A content management system (CMS) is an application used for managing content creation and modification, usually articles and blog posts containing images and videos. WordPress CMS is one of the popular CMS. CMSs make it easy to perform CRUD operations (create, read, update, and delete) without coding knowledge.
ToolJet is a free and open-source low-code app development platform that allows you to build applications quickly and has more than 30+ datasources including MongoDB that will let you seamlessly perform operations on your database. You can create a free account on ToolJet Cloud or run it on your local machine.
Many developers use databases like MongoDB and frameworks like NextJS for their full-stack web applications. Sometimes performing CRUD operations can be time taking for developers and can be hectic for someone who is not familiar with running database queries. In this tutorial, we will build an app using ToolJet that will solve these problems. The CMS app will be connected to the MongoDB database to perform CRUD operation, and the changes will be reflected on the NextJS application.
Want to use the app without going through the complete tutorial?
- Import the exported application JSON file to your ToolJet account. Here's the file.
- Once imported the application, you'll need to connect the MongoDB datasource using host details or connection string.
Prerequisites
- MongoDB database: You can set up the MongoDB database locally or use Atlas. For this tutorial, we are going to use Atlas.
- ToolJet (https://github.com/ToolJet/ToolJet): A free and open-source low-code platform that allows you to build applications quickly. Sign up here.
- NextJS app: We will learn how to build one sample app using the command line later in this tutorial.
Setting up the database
Once you have created an account on MongoDB Atlas, you'll be asked to enter the username
and password
for your database (not the same as what you use to log into the MongoDB cloud). Once done, you'll be redirected to your project's database deployment, where you can create/manage Clusters. You can create a new Cluster and choose a configuration according to your preference.
As you can see in the screenshot above, we have Cluster0
deployed. Go to the browse collections
and create a new database cms
with three collections posts
, authors
, and tags
.
-
posts
- this collection will store all the blog posts information -
authors
- this collection will store information on all the authors -
tags
- this collection will store the tags
Let's insert at least one sample document in each collection. For posts:
-
_id
: the object id will be generated by MongoDB automatically. -
title
: enter the title of the blog posts. -
subtitle
: enter the subtitle -
content
: enter the content/body of blog posts -
cover
: enter the URL of the cover image -
author_name
: enter the name of the author -
tag_name
: enter the tag name -
published_on
: enter the date in DD/MM/YYYY format The data type of all the records should be string.
Similarly, we will insert documents in authors and tags. For authors
-
_id
: the object id will be generated by MongoDB automatically. -
author_name
: name of the author -
author_email
: email of the author -
author_image
: URL of author's headshot image
For tags
:
-
_id
: the object id will be generated by MongoDB automatically. -
tag_name
: name of the tag
Once you have inserted the sample documents in all three collections, we are good to go. Our database is ready.
Now, let's go to ToolJet and connect the database.
Connecting MongoDB to ToolJet
Let's go to the ToolJet dashboard and create a new app. Once you click the New App button, an untitled app will open in the app builder. You can rename the app from the toolbar. On the left sidebar, you'll find the third option for adding or editing datasources.
Click on the + add datasource and a modal will pop up with a list of all the available datasources. Select MongoDB from the list and enter the credentials for connecting.
For this tutorial, we are using MongoDB Atlas to connect to MongoDB datasource using the connection string.
You can find your connection string by going to the MongoDB Atlas dashboard. Go to Database Deployments
on the Atlas and click on the Connect button next to the cluster name ( Cluster0 in our case). A connection dialog will pop up to choose the method by which you want to connect, click on the second option - Connect your application. Once you click on the second option, you'll get the connection string - click on the copy button next to it to copy the string.
The string that you'll copy will be like this mongodb+srv://testusername:<password>@cluster0.nc8nial.mongodb.net/?retryWrites=true&w=majority
where testusername
is the database username that we created before, we will need to replace <password>
with the password that we created for this database and then remove everything after .net/
and add your database name - in our case, the name of the database is cms
.
So, the actual connection string will be: mongodb+srv://testusername:fakepassword@cluster0.nc8nial.mongodb.net/cms
Copy-paste the connection string on the ToolJet and click on the test connection button to test the connection before saving the datasource once the connection is successful then save the datasource.
Now, that we have successfully connected the MongoDB database, we can build the user interface of the CMS app.
Build the UI of the CMS app
Let's start building the UI of the CMS application using ToolJet, which is a low-code application development platform.
The CMS application is a multi-page application that will have the following 5 pages:
All Posts
New Post
Edit Post
View Post
Authors and Tags
In the previous section, we connected the MongoDB datasource to a new application. Now, all we need to do is build the UI and then create queries and connect them with the UI.
The very first thing we are going to do is create Pages in our application. We can find the Pages option on the left sidebar from where we can add the pages to the application. Let's add the following pages:
- all_posts
- new_post
- edit_post
- view_post
- authors_tags
💡 Before we begin with UI, it is recommended to learn about ToolJet's app builder: https://docs.tooljet.com/docs/app-builder/overview
All Posts: UI
The All Posts page will show the list of all the blog posts. This is going to be the home page of the application, and from this page, we can navigate to other pages.
This page will use the listview component to show a list of blogs and buttons to navigate other pages. Let's build the UI:
- Let's drag a container on the canvas and increase its height to reach the bottom and its width to both sides. You can click on the handle of the container to edit its properties.
- Drag a text component and set its value to
<h1>All Posts</h1>
. Yes, we can use HTML tags inside the text component to format text value. - Drag a divider below the text component.
- Now drag two button components above the right side of the divider and style the buttons.
- For the first button, we will set the button text to New Post and edit its Styles. Set the button color to
#14171a
, text color towhite/#ffffff
, loader color towhite
, border-radius to2
, border color to#14171a
- Add an Event Handler to the New Post button, choose switch page action, and then select the
new_post
from the dropdown. Now, whenever the button is clickedNew Post
page of the application will be loaded.
- For the second button, we will set the button text to Authors and Tags and edit its Styles. Set the button color to
white/#ffffff
, text color to#14171a
, loader color to#14171a
, border-radius to2
, border color to#14171a
- Add an Event Handler to the Authors & Tags button, choose switch page action, and select the
authors_tags
from the dropdown. Now, whenever the button is clickedAuthors & Tags
page of the application will be loaded.
- Now drag a listview component below the divider. Go to its Styles and set the border color to white.
- Let's add components inside the listview. Remove the image component, and add three text components and two buttons as shown in the image below.
- Currently, the listview looks very rough since we haven't styled the nested components (text and buttons) yet. To make it look better, we can add some styling to the components and some placeholder text until we create the query for the data to be loaded into the listview.
- Let's edit the properties and styles of the nested text components and buttons:
- text1: Text =
Title of the blog
, Font weight =Bold
, Font size =16
- text2: Text =
By Author - 06/02/2023
, Font weight =Lighter
- text3: Text =
Tag
, Font weight =Lighter
- button1: Button text = 👁️ , Background color =
white
, Border radius =2
, Border color =#e2e4e4
- button2:
Button
text = ✏️ , Background color =white
, Border radius =2
, Border color =#e2e4e4
- text1: Text =
- For the view/👁️ and edit/✏️ buttons inside listview, we need to add event handlers. On both buttons, we need to add an event handler for
set variable
event that creates a variableselectedListViewIndex
and the variable value will be{{listItem._id}}
- this value will be there once we create the query. Another event handler that we need to add is to switch the page, for the edit button linkedit_post
page and for the view button linkview_post
page.
The UI of the All Posts page is almost finished, now let's go ahead and build the queries and connect to the UI.
All Posts: Queries
Let's build the required query for loading the data on All Posts page. Since we are only loading the list of all the blogs from the database on the listview, we need to build a single query:
posts
- Go to the query panel at the bottom of the app builder, create a new MongoDB query, and name it as
posts
- Select the Find Many Operation from the dropdown options and then enter the Collection name as
posts
which is the name of the collection in ourcms
db that we created in MongoDB Atlas - From the Advanced section, toggle on the
Run query on application load?
option, and then save the query. This will execute the query every time the app is loaded. - Run the query to trigger it, and we can check the data returned by the query from the inspector panel on the left sidebar.
authors
- Create a new MongoDB query, and name it as authors
- Select the
Find Many
Operation from the dropdown options and then enter the Collection name asauthors
which is the name of the collection in our cms db that we created in MongoDB Atlas - From the Advanced section, toggle on the
Run query on application load?
option, and then save the query. This will execute the query every time the app is loaded. - Run the query to trigger it and we can check the data returned by the query from the inspector panel on the left sidebar.
tags
- Create a new MongoDB query, and name it as
tags
- Select the
Find Many
Operation from the dropdown options and then enter the Collection name astags
which is the name of the collection in our cms db that we created in MongoDB Atlas - From the Advanced section, toggle on the
Run query on application load?
option, and then save the query. This will execute the query every time the app is loaded. - Run the query to trigger it and we can check the data returned by the query from the inspector panel on the left sidebar.
All Posts: Connecting queries data to UI
- Now, that we have the
posts
,authors
, andtags
data from the database, we can populate the listview component. Edit the properties of the ListView component and set the List data value to{{queries.posts.data}}
.
- The rows will be added to the listview but the actual data won't show up because the components inside the listview currently hold the placeholder values. Let's remove the placeholder values from the components inside the ListView. Go to the text component whose value is
Title of the blog
and set its value to{{listItem.title}}
- Set the value of the second text component to
By {{listItem.author_name}} - {{listItem.published_on}}
- Set the value of the third text component to
{{listItem.tag_name}}
We are finally done with the All Posts page, all we need to do now is build the UI of the remaining 4 pages and then connect the queries.
New post: UI
The New Post page will be used to create a new blog post and insert it into the collection posts
. Let's click on the New Post button on the top of the All Post page and switch to the new_post
page as we have already added the event handler to the button.
This page will use the container component as the body and we will nest components like text, text-input, dropdown, etc. to create a form-like structure for getting the input from the users. Let's build the UI:
- We are going to build a UI similar to the UI that we build for the All Posts page. First, we will drag a container component onto the canvas and then we will use the text component for the Title of the page i.e
New Post
with a divider component below it. - On the right side of the divider, we can simply copy and paste the
Authors & Tags
button from the All posts page and paste it into the New Post page. Change the button text to < Back and add the event handler to switch the page toall_posts
- Now we are going to drag components and build a form-like structure below the divider component.
- We are going to drag a text component, set its value to Title, set Font weight to Bold, and Font Size to 16
- We will copy-paste(using keyboard shortcuts) the Title text component 5 more times and then change their text to Subtitle, Content, Cover Image, Author, and Tag, respectively.
- Now, we will place the following components next to the headings:
- Title: text input component and set placeholder to Title
- Subtitle: text input component and set placeholder to Subtitle
- Content: text area component and set placeholder to Content
- Cover Image: text input component and set placeholder to Cover Image
- Author: dropdown component and set placeholder to Author
- Tag: dropdown component and set placeholder to Tag
- Set the value of the border radius of all the input components to
{{2}}
to make them look better
- Our form is almost complete, now at the bottom of the page we will add a button. We will copy-paste the button from the All Posts page and change the button text to Submit. Remove the existing event handlers, and add an event handler to switch the page to
all_posts
. We will add another event handler once we create the query for submitting the form.
The UI for creating a new blog post is ready, now let's create the query for inserting the form values into the database.
New post: Queries
add_post
- Create a new MongoDB query, and name it as add_post
- Select the
Insert One
Operation from the dropdown options and then enter the Collection name asposts
which is the name of the collection in our cms db that we created in MongoDB Atlas - In the Document field, enter the following:
{title: "{{components.textinput1.value}}", subtitle: "{{components.textinput2.value}}", content: "{{components.richtexteditor1.value}}", cover: "{{components.textinput3.value}}", author_name: "{{components.dropdown1.value}}", tag_name: "{{components.dropdown2.value}}", published_on: "{{moment().format("DD/MM/YYYY")}}" }
- In the code snippet above, we are dynamically getting values from the input components.
- Go to the bottom of the query manager and add the event handler to run the query on the Query Success event and select the posts query. Doing this will trigger the posts query every time this add_post query is successful or simple words whenever the user submits the blog then the list of the blogs will be refreshed on the front-end. Finally, Save the query.
New post: Connecting queries data to UI
On this page, all we need to do is connect the query that we created in the previous step to the submit button so that whenever the button gets clicked, the query for inserting the post is triggered and then the page switches to the home page i.e. All Posts page.
- Click on the handle of the Submit button, and go to the Events section under its properties.
- While building the UI we already added an event handler for switching the page to
all_posts
, now we need to add another event handler to Run the query on the On Click event -> Select theadd_post
query. Move the Run query event handler above the Switch Page event handler to ensure the query runs first and then the page switches to the home page.
Edit post: UI
This page is going to be the clone of the New Post page; we will replace the Submit button with the update button and will add another button for deleting the selected post. Let's go!
- Let's go to the New Post page and select the container. Press
ctrl/cmnd+c
, go back to the Edit Post page and pressctrl/cmnd+v
, doing this will clone the container entirely including the nested components from the New Post page. - Change the Title from
New Post
toEdit Post
- Set the default values of the following input components:
- Default Value for Title's text input :
{{queries.posts.data.filter(post => post._id == variables.selectedListViewIndex)[0].title}}
- Default Value for Subtitle's text input :
{{queries.posts.data.filter(post => post._id == variables.selectedListViewIndex)[0].subtitle}}
- Default Value for Content's text area :
{{queries.posts.data.filter(post => post._id == variables.selectedListViewIndex)[0].content}}
- Default Value for Cover Image's text input:
{{queries.posts.data.filter(post => post._id == variables.selectedListViewIndex)[0].cover}}
- Default Value for Author's dropdown component:
{{queries.posts.data.filter(post => post._id == variables.selectedListViewIndex)[0].author_name}}
- Option Value for Author's dropdown component:
{{queries.authors.data.map(i => i.author_name)}}
- Option Labels for Author's dropdown component:
{{queries.authors.data.map(i => i.author_name)}}
- Default Value for Tag's dropdown component:
{{queries.posts.data.filter(post => post._id == variables.selectedListViewIndex)[0].tag_name}}
- Option Value for Tag's dropdown component:
{{queries.tags.data.map(i => i.tag)}}
- Option Labels for Tag's dropdown component:
{{queries.tags.data.map(i => i.tag)}}
- Default Value for Title's text input :
- Let's go to Submit button and change the button text to Update. We will keep both the event handlers as it is and will replace the query in the Run Query handler later once we build the query.
- Copy the Back button from the top and paste it below next to the Update button. Change the button text to Delete. We will add the event handler in the next section when we create the query. Go to the Styles, change the button text and border color to red.
The UI of the Edit Post section is finished. We also updated the default values of the components so that whenever a listItem is clicked from the homepage the details of the selected blog details get updated on the edit page field values.
Edit post: queries
delete_post
- Create a new query from the query panel, and name it
delete_post
- Select the
Find one and delete
Operation from the dropdown options and then enter the Collection name asposts
- In the Filter field value enter:
{"title":"{{queries.posts.data.filter(post => post._id == variables.selectedListViewIndex)[0].title}}"}
- Scroll to the bottom, add an event handler to run the query on the Query Success event and select the
posts
query and then Save the query.
update_post
- Create another MongoDB query from the query panel, and name it
update_post
- Select the
Find one and update
Operation from the dropdown options and then enter the Collection name asposts
- In the Filter field value enter:
{"title":"{{queries.posts.data.filter(post => post._id == variables.selectedListViewIndex)[0].title}}"}
- In the Update field value enter:
{ $set: {title:"{{components.textinput1.value}}", subtitle:"{{components.textinput2.value}}", content:"{{components.richtexteditor1.value}}", cover:"{{components.textinput3.value}}", author_name:"{{components.dropdown1.value}}", tag_name:"{{components.dropdown2.value}}"} }
- Scroll to the bottom, add an event handler to run the query on the Query Success event, and select the posts query and then Save the query.
Edit post: Connecting queries data to UI
Now, all we need to do is update the event handlers on the Update and Delete buttons.
- Click on the handle of the Delete button to edit its properties. Go to Events, and change the query in the Run Query event to
delete_post
- Similarly, we will update the event handler of the Update button. Open its properties, go to Events, and change the query in the Run Query event to update_post
View post: UI
This page will be loaded when the 👁️/view button is clicked next to the item in the listview on the All Posts page. Let's build the UI:
- Go to the home page/All Posts page and click on the 👁️/view post button next to the list item to load the
view_post
page - Once the
view_post
page is loaded, drag a container component onto the canvas. Expand the container completely both vertically and horizontally to fit the entire canvas. Go to either of the page
New Post
orEdit Post
, copy the back button and paste it on theview_post
page. Drag a divider component below the button.
-
Now let's drag the following components and set their properties and styles:
- text component for showing the Title: text =
{{queries.posts.data.filter(post => post._id == variables.selectedListViewIndex)[0].title}}
, font weight = bold, font size = 16 - text component for showing the Subtitle: text =
{{queries.posts.data.filter(post => post._id == variables.selectedListViewIndex)[0].subtitle}}
, font weight = bold, font size = 15 - text component for showing the Author: text = Author:
{{queries.posts.data.filter(post => post._id == variables.selectedListViewIndex)[0].author_name}}
, font weight = bold, font size = 14 - image component for displaying the Cover Image: URL =
{{queries.posts.data.filter(post => post._id == variables.selectedListViewIndex)[0].cover}}
- text component for showing Content: text =
{{queries.posts.data.filter(post => post._id == variables.selectedListViewIndex)[0].content}}
, font weight = normal, font size = 14
- text component for showing the Title: text =
View post: Queries
This page doesn't requires any queries. The data on this page is loaded using the queries that we created previously.
View post: Connecting queries data to UI
We have already connected the data while building the UI. We are using variables that we created previously to filter the data according the clicked list item.
For ex: for loading the Title of the selected list view item we have set the value:
{{queries.posts.data.filter(post => post._id == variables.selectedListViewIndex)[0].title}}
Authors & Tags: UI
We are finally at the last page of the application. In this page we are going to display the list of all the author and all the tags. From this page we can perform CRUD operations on authors
and tags
collection in database. Let's build the UI:
- Go to the homepage/All Posts page of the application and click on the
Authors & Tags
button on the page, this will redirect you to theauthors_tags
page - Drag a container onto the canvas and resize(both vertically and horizontally) it to fit the canvas. Copy the back button from any of the other pages and paste it on the top-right of this page
- Let's add two text components use html tags to make them into Title: Authors, Tags
- Add two divider components below the titles and two tables respectively.
Now, we will be adding two buttons, one for adding the authors into the database and the other for adding tags into the database. We can copy the New Post button from the home page to keep the styling same. Remove the event handlers and change the button text to +Add.
Drag three modals somewhere below the container. These modals will be shown when the following buttons are clicked: +Add button for Authors, +Add button for tags, and View action button on Authors table.
Toggle off the
Use default trigger button
for all the three modals.
-
Go to the properties of +Add button for Authors, add an event handler to show the modal1. Click on the button to show the modal1. Once the modal loads click somewhere outside the modal, then drag the components from the components library onto the modal:
- 3 text components: Author Name, Author Email, and Author Image
- 3 text input components : name, email, image URL
- A button component for triggering the query that we will create in the next section, set the button text to
Add
- Just like the +Add button for Authors, we are going to add an event handler on the +Add button for tags to trigger modal2, open the modal and add the following components inside the modal:
- 1 text input components: Tag
- A button component for triggering the queries that we will create in the next section, set the button text to Add Tag
Go to the Authors Table, add two Action buttons: View and Remove. On View action button, we will add an event handler to show the modal3 and the Remove action button will trigger the query that will remove the selected author from the collection.
-
Click on the View button to show the modal, add components inside the modal3 just like we have added components in the previous 2 modals:
- 2 text components: text =
{{components.table1.selectedRow.author_name}}
&{{components.table1.selectedRow.author_email}}
, keep the font weight = bold for the first text component. - 1 image component to display the author image:
{{components.table1.selectedRow.author_image}}
- 2 text components: text =
Go to the Tags Table, and add one Action button: Delete. This action button will trigger the query that will remove the selected tag from the collection.
Authors & Tags: Queries
add_authors
- Create a new MongoDB query, name it
add_author
, selectinsert one
from the operations dropdown, and enterauthors
in the collection field. - In the Document field, enter:
{author_name: "{{components.textinput1.value}}", author_email: "{{components.textinput2.value}}",author_image: "{{components.textinput3.value}}" }
- Go to the bottom, and add an event handler to run authors query on Query Success Event. Finally, Save the query.
add_tags
- Create a new MongoDB query, name it
add_tag
, selectinsert one
from the operations dropdown, and entertags
in the collection field. - In the Document field, enter:
{tag:"{{components.textinput4.value}}"}
- Go to the bottom, and add an event handler to run tags query on Query Success Event. Finally, Save the query.
delete_author
- Create a new MongoDB query, name it
delete_author
, selectdelete one
from the operations dropdown, and enterauthors
in the collection field. - In the Filter field, enter:
{"author_name":"{{components.table1.selectedRow.author_name}}"}
- Go to the bottom, and add an event handler to run
authors
query onQuery Success
Event. Finally, Save the query.
delete_tag
- Create a new MongoDB query, name it
delete_tag
, selectdelete one
from the operations dropdown, and entertags
in the collection field. - In the Filter field, enter:
{"tag":"{{components.table2.selectedRow.tag}}"}
- Go to the bottom, and add an event handler to run
authors
query on Query Success Event. Finally, Save the query.
Authors & Tags: Connecting queries data to UI
Let's connect the queries to the table components to display the data and the button components for triggering the insert and delete queries:
- Go to the Author's table, edit its properties, and set table data to
{{queries.authors.data}}
. The columns will be auto-populated. Enable the highlight selected row from the options and set the loading state of the table to{{queries.delete_author.isLoading || queries.authors.isLoading}}
- Edit Remove action button and add the event handler to run the
delete_author
query. This will remove the author from the database whenever the action button is clicked.
- Click on the +Add Authors button to show the modal, inside modal, there is a Add button for submitting the form. Add the following event handlers to this button:
-
1st event handler to run the query:
add_author
- the next 3 event handlers to
control the component
. Components will be the three text inputs that are there in the modal and the Action will be Clear . Adding these event handlers will clear the form as soon as theadd_author
query is triggered. - last event handler for closing the modal.
-
1st event handler to run the query:
- Now, we are going to add the event handlers to +Add button for the Tags:
-
1st event handler to run the query:
add_tag
- the next event handler to control the component. Select the text input component that is there in the form and set the Action to
Clear
. - last event handler for closing the modal.
-
1st event handler to run the query:
- Finally, go to the Tags table, and set the table data to
{{queries.tags.data}}
. The columns will be auto-populated. Enable the highlight selected row from the options and set the loading state of the table to{{queries.delete_tag.isLoading || queries.tag.isLoading}}
- Edit delete action button and add the event handler to run the
delete_tag
query.
Connecting to NextJS app
Using the connection string, we can connect the MongoDB Atlas database to any NextJS app. In this section, we will locally set up a NextJS application and then connect it to the MongoDB database to load the data on the front end.
Requirements:
- MongoDB Atlas database
- NodeJS 12+
- npm and npx
- Vercel (Optional if you want to deploy your NextJS app)
Building NextJS app
Go to the terminal, and enter the following command:
npx create-next-app --example with-mongodb nextblog
We are using the npx create-next-app
command and are passing the --example with-mongodb
parameter which will tell create-next-app
to bootstrap our app with the MongoDB integration example. Finally, nextblog
is the name of our application.
Executing this command will take a couple of seconds to download and install all the npm dependencies, but once they're downloaded and installed, navigate to your project directory by running:
cd nextblog
Install all the npm dependencies by running:
npm install
Now, let's start up our application. To start our Next.js app, execute:
npm run dev
Once the app is built successfully, we can navigate to localhost:3000
to see our app live in action.
We will get an error similar to the one in the screenshot above because the app is built but we haven't connected our MongoDB database yet to the application. So let's do that.
Connecting MongoDB
- On the
nextblog
directory, we can find theenv.local.example
file. We can rename the file toenv.local
and then edit it. In this file, we will need to enter the value for
MONGODB_URI
andMONGODB_DB
variable.MONGODB_URI
is nothing but the connection string till / andMONGODB_DB
will be the name of the database. Go to the beginning of the tutorial to learn how we can obtain the connection string from the Atlas. Theenv.local
file will look like this:
As soon as you save these environment variables, go to the browser and you'll see that the error is gone and
with-mongodb
Next.js app welcome page is loaded.
Querying MongoDB with Next.js
The first example we'll look at is building and exposing an API endpoint in our Next.js application. To create a new API
endpoint route, we will first need to create an api directory in our pages
directory, and then every file we create in this api
directory will be treated as an individual API endpoint.
Let's go ahead and create the api
directory and a new file in this directory
called posts.js
. This endpoint will return a list of all the blog posts from our posts
collection in the MongoDB database. The implementation for this route is as follows:
import { connectToDatabase } from "../../lib/mongodb";
export default async function handler(req, res){
const {db} = await connectToDatabase();
const data = await db.collection("posts").find({}).toArray();
res.json(data);
}
Go to the lib/mongodb.ts
file and update the existing code to the following code:
import { MongoClient } from 'mongodb'
const { MONGODB_URI, MONGODB_DB } = process.env
if (!MONGODB_URI) {
throw new Error(
'Please define the MONGODB_URI environment variable inside .env.local'
)
}
if (!MONGODB_DB) {
throw new Error(
'Please define the MONGODB_DB environment variable inside .env.local'
)
}
/**
* Global is used here to maintain a cached connection across hot reloads
* in development. This prevents connections growing exponentially
* during API Route usage.
*/
let cached = global.mongo
if (!cached) {
cached = global.mongo = { conn: null, promise: null }
}
export async function connectToDatabase() {
if (cached.conn) {
return cached.conn
}
if (!cached.promise) {
const opts = {
useNewUrlParser: true,
useUnifiedTopology: true,
}
cached.promise = MongoClient.connect(MONGODB_URI, opts).then((client) => {
return {
client,
db: client.db(MONGODB_DB),
}
})
}
cached.conn = await cached.promise
return cached.conn
}
Now, if we navigate to localhost:3000/api/posts
, we'll see a result that looks like this:
Finally, let's update the pages/index.ts
file to use this JSON response and display the formatted data on the homepage.
import Head from 'next/head'
import { connectToDatabase } from '../lib/mongodb'
import { InferGetServerSidePropsType } from 'next'
import { title } from 'process';
export async function getServerSideProps(context) {
const { db } = await connectToDatabase()
const data = await db.collection("posts").find({}).toArray();
const allposts = JSON.parse(JSON.stringify(data));
return {
props: { posts: allposts },
}
}
export default function Home({ posts }) {
console.log(posts);
return (
<div>
<Head>
<title>Nextbnb</title>
<link rel="icon" href="/favicon.ico" />
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet"></link>
</Head>
<div className="md:container md:mx-auto">
<p>All Posts</p>
<ul>
{posts.map(post => (
<li key = {post._id}>{post.title} by {post.author_name} on {post.published_on}</li>
))
}
</ul>
</div>
</div>
)
}
Finally, navigate to http://localhost:3000/
!
Tada 🎉 Now you can see the posts
collection data on the homepage of the application. This is just the rough presentation of the data on the frontend - you can make further changes to improve the UI.
Putting it all together
In this tutorial, we walked through the MongoDB Atlas and created a database with three different collections, learned how to quickly build a multipage application using ToolJet, and finally, we connected our MongoDB database to the Next.js application and executed queries.
If you have any questions or feedback, reach out through the ToolJet Slack community and let me know what you want to build with ToolJet and MongoDB.
Posted on March 28, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.