How to Build a Vanilla JS Todo App with Bazaar
In this tutorial, you will build a simple Todo application using vanilla JavaScript and Bazaar. This guide will walk you through setting up the project, integrating Bazaar for backend services, and deploying your application to Netlify. By the end of this tutorial, you will have a fully functional Todo app with features to add, display, mark as complete, and delete tasks.
Prerequisites
To complete this tutorial, you will need:
- A basic understanding of JavaScript.
- Node.js installed on your machine.
- Git installed on your machine.
- A GitHub account for code repository hosting.
- (Optional) A Netlify account for deploying your app.
Step 1 — Setup a New Project
In this step, you will create the files and folders needed for your app and add some starting boilerplate.
Create a folder for your project named bazaar-vanilla-js-todo
.
Create the folders css
and js
in your new project folder. Then, create the files index.html
, css/style.css
, and js/app.js
. Your file structure will look like this:
Directorycss
- style.css
Directoryjs
- app.js
- index.html
Next, add the starting content to each of these files:
-
First, add the starting HTML to
index.html
:This HTML provides the basic structure for a web page, linking to
css/style.css
for styling andjs/app.js
for functionality. The main content area is enclosed in adiv
with the classcontainer
. Next, you’ll enhance it with some minimal CSS. -
Add the following styles to
css/style.css
: -
Finally, add the following to
app.js
:JavaScript is added within a function that runs when the
DOMContentLoaded
event occurs. This prevents global variable leakage and ensures the code runs after the DOM has fully loaded, allowing safe manipulation of HTML elements.
Your project is set up. Next, you’ll run a local HTTP server to view it in the browser.
Step 2 — Running a local HTTP Server
In this step, you’ll run a local HTTP server to view your app. While you could open the index.html
file directly in your browser, serving your app locally provides a real URL necessary for integrating Bazaar’s backend services.
Open up your terminal and ensure your project folder is the current working directory. Then, Run the following command:
That command will install (if necessary) and execute http-server, a simple HTTP server. It will serve on http://127.0.0.1:8080
by default. Check your app in the browser to see the text Todo.
Step 3 — Running the Mock Server
In this step, you will use the Bazaar mock server to develop your app locally. The mock server simulates the Bazaar backend, allowing you to test and build your application in a local environment.
In a new terminal window, run the following command to start the mock server:
This command assumes http-server
server is running on the default port, 8080
. Update accordingly if you’re running on a different port.
Install the @bzr/bazaar-mock
NPM package if prompted.
You should see output similar to this:
Now that the mock server is running, you’ll initialize a Bazaar client.
Step 4 — Initializing a Bazaar Client
In this step, you will install and initialize the Bazaar client to manage backend services for your Todo app.
You can use Bazaar directly from a CDN via a script tag. Add the script tag before the app.js
tag in index.html
:
Here you are using unpkg, but you can also use any CDN that serves NPM packages, for example jsdelivr or cdnjs.
Next, initialize the Bazaar client in app.js
:
In this code, you set the following BazaarApp
options for local development:
appId
: Usestest
, the Bazaar mock server default.loginRedirectUri
: Useswindow.location.href
as the default, e.g.http://localhost:8080/
.bazaarUri
: Useshttp://localhost:3377
, the Bazaar mock server URL.onApiConnectError
: If a connection error occurs, logs out the user.
Open the app in your browser and check the developer console. You’ll see the following:
With the Bazaar client initialized you can now add authentication to your app.
Step 5 — Adding User Authentication
In this step, you’ll add user authentication to your app using Bazaar’s OAuth2-based authentication system.
First, add log in and log out buttons to your template:
And add the corresponding click
event listeners in app.js
:
When a user clicks the log in button, a pop-up window opens, prompting them to create a Bazaar account or log in if they already have one. Once the account is created, the user is prompted to authorize your Todo app.
Create a test account by entering any email address, using the code 1234
and choosing any handle and name. Then, authorize the app. The pop-up will close. Refresh the page, and in your developer console you’ll see the following:
Next, refactor the code so the login status updates immediately after a successful login, not just on page load.
Log out and log back in, and you’ll see is logged in: true
in your console after the pop-up closes without needing a page refresh.
You have now added user authentication to your app. Next, you will conditionally display content based on the user’s login status.
Step 6 — Displaying Logged-in Content
In this step, you will conditionally display content based on the user’s login status.
First, make the following changes in index.html
:
In these changes, you add a logged-out
class to the body
tag and a main
tag, where logged-in content will be displayed.
In style.css
, notice the log out button and main
element (the logged-in content) are hidden when the logged-out
class is present:
Next, update the doLoginActions
function to display content in app.js conditionally
:
Now, on log in, the logged-out
class is removed from the body
element, displaying the log out button and the main
element. The log in button is also removed from the DOM as it’s unnecessary once a user has logged in.
The app now displays the appropriate content based on the user’s login status.
Next, you’ll add the functionality to create todos.
Step 7 — Adding a Todo
In this step, you’ll implement the feature to create todos.
In index.html
, add a form to create a todo.
These changes add a form with a single input field for the todo text. Notice that the form has no action
, you’ll add a submit event listener in JavaScript next.
Update the doLoginActions
function to add the submit event listener:
The bzr.collection
method creates an object to interact with a database collection. Learn more in the collections docs.
The submit handler takes the input value and creates a doc in the todos
collection.
Back in your browser, submit the form to create a todo. In your developer console, you’ll see the todo with the generated ID returned from the database.
You have now implemented the functionality to add new todos, but they still need to be displayed. In the next step, you will display these todos in your app.
Step 8 — Displaying Todos
In this step, you will fetch and display todos from the collection.
First, add an element to hold the todos in index.html
:
Next, update the doLoginActions
function to fetch todos and insert them into the DOM:
The insertTodoInDOM
function first makes sure an element with a todo ID doesn’t already exist. Next, it gets a reference to the <div id="todos"></div>
element you just added in index.html
and inserts the todo HTML as the first child of the todos element, ensuring the most recent todos are added to the top of the list.
Finally, you need to add a todo to the DOM when it gets added to the database. Update the submit event listenter:
You have now successfully displayed the todos fetched from the collection. In the next step, you will add realtime syncing to keep the todos updated across different devices.
Step 9 — Adding Realtime Syncing
In this step, you will enable realtime updates for your todos so that changes are reflected instantly across different devices.
Replace the todosCollection.getAll
call with todosCollection.subscribeAll
:
In this code, todosCollection.subscribeAll
subscribes to all changes in the todos
collection. You pass a subscribe listener as the second subscribeAll
argument with functions to handle onInitial
and onAdd
events. In both cases, you insert a todo into the DOM, exactly as you did in todosCollection.getAll
.
You can think of onInitial
as syntactic sugar for todosCollection.getAll
. It fetches all docs from the collection, then calls your onInitial
function for each doc.
With the onAdd
handler in place, there’s no need to add a todo to the DOM when the form is submitted. Update the submit event listener:
Learn about subscribe listeners.
To test the realtime updates, open your app in a private window while keeping the original window open. When you make changes in one window, they will appear in the other in realtime.
Realtime syncing is enabled, but it only handles add todo events. In the next step, you will implement the functionality to toggle the completion status of todos and update your subscribe listener with an onChange
handler.
Step 10 — Toggling Todo Completion
In this step, you’ll implement functionality to toggle the completion status of todos.
First, update the todo template and add an update event listener:
In these changes, you add a completed
class to a todo when it’s complete. The completed
styles are already in style.css
.
Then, you add a button and event listener for toggling todo completion. To determine if a todo is completed, you check for the presence of the completed
class. If it is present, set the todo completed
value to false
, otherwise, set it to true
.
Finally, modify the subscribe listener to handle change events.
The onChange
handler forces the presence of the completed
class to the completed
value of the changed doc by passing the value as the second argument of todoElement.classList.toggle
.
You can now mark todos as completed or incomplete. In the next step, you will add the functionality to delete todos.
Step 11 — Deleting a Todo
In this step, you will implement the functionality to delete todos.
First, update the todo template and add a click event listener:
With these changes, you add a button and event listener for deleting a todo. window.confirm
prompts the user confirmation before deleting.
Next, add a delete event handler to your subscribe listener:
The delete handler removes the todo with the corresponding ID from the DOM. The optional chaining operator (?) checks for the element’s presence before deleting it.
Show the Completed app.js
File
Show the Completed index.html
File
With that, your todo app is complete and ready to deploy.
Step 12 — Deploying to Netlify
In this step, you will deploy your Todo app to Netlify. You can deploy a Bazaar-powered app anywhere static sites can be hosted. Netlify provides a frictionless deployment process and free static site hosting for public GitHub repos.
-
To start, initialize a Git repository and push your code to GitHub:
Go to GitHub and create a public repo named
bazaar-vanilla-js-todo
. -
Next, deploy the Netlify to get your App URL
Go to Netlify, create an account if necessary, and click Add new site. Select Import an existing project and choose GitHub. Select your repository
bazaar-vanilla-js-todo
. If you can’t find your repo, click Configure the Netlify app on GitHub to grant access.Configure the site settings and build settings as follows:
- Site name: e.g.
bazaar-vanilla-js-todo
- Branch to deploy: e.g.
main
Leave the other fields blank. Note down your Netlify URL, which is found under the Site name field. Then, click Deploy.
The process will take a few minutes, after which your todo app will be deployed. However, the Bazaar config still needs to be updated. You deploy the app before updating the configuration because the app URL is required.
- Site name: e.g.
-
Register a Bazaar App
You need a Bazaar app ID to configure your Bazaar client for production.
Open cloud.bzr.dev and create a free account. Click on the user icon at the top right, then click Developers. Next, click Create App. Give your app a name. I’m using Vanilla JS Todo. Set your APP URL, which should be the same as your app’s Netlify URL, e.g.
https://bazaar-vanilla-js-todo.netlify.app
. Finally, click Create, then copy your app ID. It will look something like01907291-d4e5-79d5-a312-ba20260c9b98
. -
Update your Bazaar client config and Redeploy
Finally, you can update your Bazaar client config. As you’re not using a build step, you can’t make use of environment variables, so you’ll hardcode production values:
Make sure to replace the
appId
andloginRedirectUri
values with your own. NoticebazaarUri
is removed so it defaults to its production value.Commit your changes and push to re-deploy:
Pushing will trigger Netlify to deploy your site. In a few minutes, your todo app will be deployed!
Conclusion
In this tutorial, you built and deployed a Todo app using vanilla JavaScript and Bazaar. You set up a new project, integrated Bazaar for backend services, implemented user authentication, added and displayed todos, enabled realtime syncing, and deployed your app to Netlify.
Check the Bazaar documentation for more features and capabilities.