How to Build a Vue Todo App with Bazaar
In this tutorial, you will build a simple Todo application using Vue.js and Bazaar. This guide will walk you through setting up a new Vue 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 Vue 3.
- 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 — Scaffolding a New Vue Project
In this step, you will create a new Vue project using the official Vue project scaffolding tool. The created project will be using a build setup based on Vite.
Open up your terminal and ensure your current working directory is where you intend to create a project. Then, Run the following command:
That command will install and execute create-vue, the official Vue project scaffolding tool.
Choose the project name, bazaar-vue-todo
. Then, answer the feature prompts as follows:
These choices will set up a minimal Vue project with TypeScript support, which is sufficient for this tutorial.
Next, navigate to your project directory, install dependences, and start the development server:
Open the default URL http://localhost:5173/
in your browser to see the starter Vue project.
In the next step, you’ll prepare your project by cleaning up unnecessary scaffolded files and adding custom styles.
Step 2 — Preparing the Project
In this step, you will clean up the scaffolded Vue project by removing unnecessary files and adding custom styles.
-
First, delete the following files and folders:
src/components/*
src/assets/base.css
src/assets/logo.svg
-
Replace the contents of
src/assets/main.css
with: -
Finally, replace the contents of
src/App.vue
with the following:
Check your app in the browser to see the text Todo.
With the project cleaned up, you are ready to integrate Bazaar for authentication and realtime data storage.
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 the Vite dev server is running on the default port 5173
. 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.
First, install the Bazaar library:
Next, initialize the Bazaar client in src/App.vue
:
In this code, you set the following BazaarApp
options:
appId
: Checks for aVITE_APP_ID
environment variable and, if not present, usestest
, the Bazaar mock server default.loginRedirectUri
: Checks for aVITE_URL
environment variable and, if not present, useswindow.location.href
as the default, e.g.http://localhost:5173/
.onApiConnectError
: If a connection error occurs, logs out the user.
Open up the app in 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:
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 to your script:
In these changes, you create a reactive variable for the login status and set its value to true
when a user logs in.
Next, update the template to display log in and log out buttons conditionally:
The app now displays the appropriate button 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.
Make the following changes to your script:
In this code, you define a Todo
type and create two reactive variables, one for the new todo text and another for holding the list of todos.
The bzr.collection
method creates an object to interact with a database collection. Learn more in the collections docs.
The onSubmit
function adds a new todo to the todos
collection with todosCollection.insertOne
(collections are created lazily) and adds the todo to your app’s local state with the ID generated by the database after insertion.
Next, add the form to your template after the log out button:
In these changes, you hook up the onSubmit
handler to the form submit event and bind the todoText
reactive variable you just created to the input.
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, update the doLoginActions
function to fetch todos:
In this code, todosCollection.getAll()
fetches all the todos from the collection, and the results are stored in the todos
reactive variable.
Next, update the template to display the todos:
Add a few more todos in your browser and notice they get added to the bottom of your list. Usually you want the newest todos to appear first. To do that, you’ll reverse the fetched todos.
In these changes, you store fetched todos in a new reactive variable, fetchedTodos
, and update todos
to be a computed property that will updated when fetchedTodos
changes. The spread operator (...
) creates a new array, as the reverse
method updates an array in place. Doing fetchedTodos.value.reverse()
would cause an infinite re-render.
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.
The todos
reactive variable is an array so you can use the arrayMirrorSubscribeListener
helper. Import it:
Then, update the onSubmit
and doLoginActions
methods as follows:
In this code, todosCollection.subscribeAll
subscribes to all changes in the todos
collection, and arrayMirrorSubscribeListener
handles change events, ensuring the local todos
array stays in sync with the collection. As such, in onSubmit
, you no longer need to add the todo to your local state. Learn about subscribe listeners.
To test the realtime updates, open your app in a private window while keeping the original window open, and log in. When you make changes in one window, you’ll see them appear in the other in realtime.
With realtime syncing enabled, any changes to the todos will be updated instantly. In the next step, you will implement the functionality to toggle the completion status of todos.
Step 10 — Toggling Todo Completion
In this step, you’ll implement functionality to toggle the completion status of todos.
First, add the toggleTodoCompletion
function:
That function updates the completed
value for a todo, setting it to the opposite of its current state. Remember, you don’t need to update your local state. The arrayMirrorSubscribeListener
helper keeps your local state in sync with the database.
Next, update the template to include a button for toggling the completion status and conditionally style the todo text:
In this template, the strikethrough
class is applied to the todo text if the todo is marked as completed, and a button is added to toggle the completion status.
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, add the deleteTodo
function:
Here, window.confirm
prompts the user confirmation before deleting. Again, arrayMirrorSubscribeListener
will handle the onDelete
event and update your local state.
Next, update the template to include a button for deleting todos:
That code change will render a delete button for each todo.
Show the Completed App.vue
File
With that, your todo app is complete and ready to deploy.
Step 12 — Deploying to Netlify
In this step, you will deploy your Vue.js 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.
First, initialize a Git repository and push your code to GitHub:
Go to GitHub and create a public repo named bazaar-vue-todo
.
Next, 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-vue-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-vue-todo
- Branch to deploy: e.g.
main
- Build command:
npm run build-only
(default) - Publish directory:
dist
(default)
Add environment variables VITE_URL
and VITE_APP_ID
. For VITE_URL
, use your app’s Netlify URL (e.g., https://bazaar-vue-todo.netlify.app
).
To get your Bazaar app ID, 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 Vue Todo. Set your APP URL, which should be the same as your app’s Netlify URL, e.g. https://bazaar-vue-todo.netlify.app
. Finally, click Create, then copy your app ID. It will look something like 01907291-d4e5-79d5-a312-ba20260c9b98
.
Return to Netlify and paste in your app ID as the VITE_APP_ID
value, and click Deploy. You’ll see a notice, Site deploy in progress. The process will take a few minutes, after which your todo app will be deployed!
Conclusion
In this tutorial, you built and deployed a Todo app using Vue.js and Bazaar. You set up a new Vue 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.