Node express showing Notion results in the front end


Getting our Notion results to the front end in our node express website

9 Sep, 2021 · 5 min read

We now have a Node API that can query our Notion database results. We’ll explore how we can show these results in the front end!

This is a series on building a Node powered Notion API:

Query our Node API from the frontend

So at this stage, we can query our Node API by visiting the /movies endpoint. However, we want to query this from our front end and work with this data.

Let’s modify our HTML, include the JavaScript link, and create a placeholder div where we can render our data.

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Notion API Test</title>
    <link rel="stylesheet" href="styles/style.css" />
    <div class="flex flex-wrap" id="movie-container"></div>
    <script type="module" src="./script.js"></script>

Let’s go ahead and create the script.js file in your public folder. We will add the logic in querying our database and showing the results in our HTML file.

The very first thing we should do is define our movie container div. That will be the element we will add our movies into.

const movieContainer = document.getElementById('movie-container');

Then let’s create a function that will fetch all the movies from our Node database.

const getMovies = async () => {
  const rest = await fetch('http://localhost:8000/movies');
  const data = await rest.json();
  return data;

Then let’s create a function to show the movies.

const showMovies = async () => {
  const movies = await getMovies();

  movies.forEach((movie) => {


As you can see, this function is also the one invoked. What happens is it will get our movies and await the results.

Once the results are there, it will loop over each movie and log it in our console.

Each movie object looks like this:

  banner: ""
  id: "7405664d-d341-4ecd-9057-ca083a83a71b"
  name: "Shershaah"
  tags: ["drama", "action", "biography"]
  watched: false

Adding movies to our frontend

Then it’s time to add a div for each of our movies. From our Node express Tailwind example, you might remember that we already have a layout we can use.

The HTML for it looks like this:

<div class="w-1/4 p-4">
  <div class="relative pb-[200%]">
      class="absolute object-cover w-full h-full rounded-lg shadow-md"
  <div class="relative z-10 px-4 -mt-8">
    <div class="p-6 bg-white rounded-lg shadow-xl">
        class="inline-block px-2 text-xs font-semibold tracking-wide text-blue-800 uppercase bg-blue-200 rounded-full "

We need to use the JavaScript createElement method.

I like to work top-down, so let’s start with the wrapping div. As you can see, it’s a plain div with the classes: w-1/4 p-4.

const movieDiv = document.createElement('div');
movieDiv.className = 'w-1/4 p-4';


The above code will create a div element with those class names and append it to our wrapping div. However, since there is no content yet, we can only see this in the HTML structure.

Dynamic added div

The next element we have is the wrapping div around the image, so let’s create that one.

const imageDiv = document.createElement('div');
imageDiv.className = 'relative pb-[200%]';


Here we create the image div and append it to the movie div since it’s a child of this element.

The next element we need is the actual image. Let’s go ahead and create that.

const image = document.createElement('img');
image.src = movie.banner;
image.alt =;
image.className = 'absolute object-cover w-full h-full rounded-lg shadow-md';


As you can see, this is the first part where we use the dynamic data to set the src of the image and the alt text.

By now, we should see something in our front end.

Rendered movies in our frontend

Now let’s move to the div below the image that holds our text elements and tags. There are two main wrapping divs here, one as a container and one for the card styling.

const textContainerDiv = document.createElement('div');
textContainerDiv.className = 'relative z-10 px-4 -mt-8';

const textCardDiv = document.createElement('div');
textCardDiv.className = 'p-6 bg-white rounded-lg shadow-xl';


When playing with these appendChild types, you might get overwhelmed about where to place each item. It helps a lot by naming them correctly, so you remember what each element does.

Then inside the text card, we have a title and some tags. Let’s do the title first.

const title = document.createElement('h2');


As you can see, for the h1 element, we use a text node element, which is the advised way to create such an element.

Then it’s time to move to our tags, the last thing to make our card. We want to loop over each tag and create a span element for it.

movie.tags.forEach((tag) => {
  const tagSpan = document.createElement('span');
  tagSpan.className =
    'inline-block px-2 mr-2 text-xs font-semibold tracking-wide text-blue-800 uppercase bg-blue-200 rounded-full';

And with that, we have our complete code setup!

Go ahead and add a movie in your Notion document 👀

Complete notion node express app

There is only one small thing we need to do. Since we moved our class names to a JavaScript file, we have to notify Tailwind to purge our JS files. Open the tailwind.config.js file and add the following purge:

purge: ['./public/*.html', './public/*.js'],

If you want to view the complete code again, I’ve uploaded it to the following GitHub branch.

Thank you for reading, and let’s connect!

Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter

Spread the knowledge with fellow developers on Twitter
Tweet this tip
Powered by Webmentions - Learn more

Read next 📖

NVM set default version

20 Jul, 2022 · 2 min read

NVM set default version

Managing multiple node versions with NVM

13 Jul, 2022 · 2 min read

Managing multiple node versions with NVM

Join 2099 devs and subscribe to my newsletter