This tutorial will guide you in building a dynamic and beginner-friendly To-Do App using Nuxtjs 3 and Altogic. By following the steps, you will learn how to create an app that has both frontend and backend features. Nuxtjs makes it easy to build fast and interactive apps while Altogic handles the backend, allowing you to focus on the frontend. With Altogic, you can add a creative touch to your To-Do App. This step-by-step guide will cover the use of Altogic Client Library to create a simple to-do app.
What is Altogic?
Altogic backend as a service platform allows you to create and start running your backend apps in minutes. With your backend apps, you can manage your application data in a database, cache your data in memory, execute database transactions to ensure data integrity, run complex business logic through synchronous and asynchronous services, manage user sessions, schedule jobs to be executed at a specific time or interval, send and receive real-time messages through WebSockets and more.
What is Nuxt.js?
Nuxt.js is a JavaScript framework that helps you build server-rendered Vue.js applications. It provides a powerful development environment and a set of features such as async data, middleware, and layouts to make building universal apps a breeze. Nuxt.js also helps with the configuration and development of your application's Nuxt.js specific features such as the routing, and the handling of the webpack build process.
Setting up Development Environment
To complete this tutorial, ensure you have installed the following tools and utilities on your local development environment.
- VsCode
- NodeJS
- Nuxtjs
- You also need an Altogic Account. If you do not have one, you can create an account by signin up for Altogic.
Creating an Altogic Account
After creating an account, you will see the workspace and repository page. You can create a new app by clicking the + New app
button.

Click + New app
and follow the instructions;
- In the App name field, enter a name for the app.
- Enter your subdomain.
- Choose the deployment location.
- And select your free execution environment pricing plan.

For this tutorial, we will use the blank template. So, select the Blank template and click Next
.
note
In the template section, you can choose the template you want to use. Basic template creates a default user data model for your app, which is required by Altogic Client Library to store user data and manage authentication. If you don't need authentication, you can use the Blank template.
Later, if you want, you can easily create a new data model manually and from the App Settings → Authentication mark this new data model as your user data model.

Awesome! We have created our application; Now click/tap on the newly created app to launch the Designer. In order to access the app and use the Altogic client library, we should get envUrl
and clientKey
of this app.
Click the Home section in the left menu and copy the API base URL and Master client key for your app.

info
In this tutorial we don't need authentication. So, let's disable session based authentication from the App Settings → Client library keys → Master client key view of Altogic Designer.

By clicking the Enforce session
checkbox, you can disable session based authentication. Now, we are ready to start building our app.
Creating a Nuxt.js project
Open your terminal and navigate to the directory where you want to create your project. Then run the following command to create a Next.js project.
npx nuxi init nuxt-todo-app

Designing the User Interface
Installing Tailwind
Open your terminal and navigate to the project directory. Then run the following commands to install Tailwind CSS. You can also follow the official Tailwind CSS documentation to install Tailwind CSS in your Next.js project.
npm install --save-dev @nuxtjs/tailwindcss
# OR
yarn add --dev @nuxtjs/tailwindcss
Open the nuxt.config.js
file and replace the code with the following code:
export default defineNuxtConfig({
modules: ["@nuxtjs/tailwindcss"],
});
Creating the UI
Open app.vue
file and replace the code with the following code:
<template>
<div class="max-w-2xl mx-auto py-8 px-4 sm:py-12 sm:px-6 lg:max-w-7xl lg:px-8">
<form>
<div class="relative">
<input
placeholder="Add Todo"
class="w-full rounded-md border-gray-200 py-2.5 pr-10 pl-2 shadow-sm sm:text-sm border-2 border-dashed"
/>
<span class="absolute inset-y-0 right-0 grid w-10 place-content-center">
<button type="submit">
<span class="sr-only">Submit</span>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
aria-hidden="true"
id="send-icon"
class="w-7 h-7 text-gray-500"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M13 9l3 3m0 0l-3 3m3-3H8m13 0a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
</button>
</span>
</div>
</form>
<div class="flex items-center justify-between mt-2">
<div class="relative flex items-center">
<div class="flex items-center h-5">
<input
type="checkbox"
class="focus:ring-indigo-500 h-6 w-6 text-indigo-600 border-gray-300 rounded cursor-pointer"
/>
</div>
<div class="ml-3 text-sm w-full p-2 cursor-pointer">
<label class="font-medium text-gray-700 cursor-pointer"> </label>
</div>
</div>
<div class="flex items-center px-2 py-2 text-sm font-medium rounded-md">
<button>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
aria-hidden="true"
class="lex-shrink-0 h-5 w-5"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
/>
</svg>
</button>
</div>
</div>
</div>
</template>
Okay, now we have a basic UI for our app. Let's run the following command to start the development server.
npm run dev
Creating the Backend
As we mentioned earlier, we will use Altogic to create the backend for our app. Altogic is a serverless backend as a service platform that provides authentication, database, and other services. You can create a free account on Altogic and create a new app.
Creating Todo Model
- Click/tap on Models on the left sidebar.
- Click New on the right of the screen and select model.
- Set model name as todo.
- Ensure that the Enable timestamps is selected.
- Click Next

With using Altogic you can automatically generate Rest API for your models. You can also create custom API endpoints. Since we will use the Altogic Client Library, we won't use these endpoints.

We have created a todo
model, now we need to add fields for to our model. For this tutorial, let's create two fields for our model. One for the name of the todo and the other for the status of the todo.
Let's create the first field. We will create a text field for the name
of the todo.
- Click/tap on the todo model on the Models page.
- Click/tap on New Field at the right-top of the page.
- Select field type as Text Field then select Text.
- Set field name as
name
- Ensure that the Required is selected.
- Click Create.

Let's create the second field. We will create a boolean field for the isCompleted
of the todo.
- Click on New Field on the right-top of the page.
- Select Boolean.
- Set field name as
isCompleted
- Ensure that the Required is selected.
- Set default value expression false.

Ah yes, we have created our model and fields and completed the database design visually with using Altogic without any coding and complex configuration. Let’s move on to the front-end development.
Integrating Frontend with Backend
Now we have a basic UI for our app and a database design. Let’s integrate our Nuxtjs app with the backend. We will use Altogic Client Library to integrate our frontend with the backend.
Installing Altogic Client Library
You can install the Altogic Client Library with using npm or yarn. Open your project directory and run the following command to install the Altogic Client Library.
# using npm
npm install altogic
# OR is using yarn
yarn add altogic
Let’s create a configs/
folder in the root of the project directory and create a altogic.js
file in the configs/
folder.
Open altogic.js
and paste below code block to export the altogic client instance.
// configs/altogic.js
import { createClient } from "altogic";
// This `envUrl` and `clientKey` is sample you need to create your own and replace it.
let envUrl = "https://todo.c1-na.altogic.com";
let clientKey = "e574fee1fb2b443...a8598ca68b7d8";
const altogic = createClient(envUrl, clientKey);
export default altogic;
note
You can find your envUrl
and clientKey
in the Home or Settings view of your app. You can also create a new environment and get the envUrl
and clientKey
for the new environment.
Creating State for Todo List
Let’s create a state for our todo list. We will use React Hooks to create our state. Open app.vue
and paste below code block to create our state.
<script setup>
const todos = ref([]);
const todoInput = ref("");
</script>
Fetching Todo List
The next step is to fetch the todo list from the database. We will use Altogic Client Library to fetch the todo list from the database. Open app.vue
and paste below code block to fetch the todo list from the database.
Let's create below function to fetch the todo list from the database. In this tutorial we will fetch the first 100 todos from the database. You can fetch the todos with using pagination and limit. You can also fetch the todos with using filters and sorting. You can find more information about fetching data from the database in the Altogic Client Library documentation.
<script setup>
import altogic from "~/configs/altogic";
const { data, errors } = await useAsyncData(() =>
altogic.db.model("todo").page(1).limit(100).get()
);
const todos = ref(data.value.data);
const todoInput = ref("");
</script>
<div
v-for="todo in todos"
:key="todo._id"
class="flex items-center justify-between mt-2"
>
<div class="relative flex items-center">
<div class="flex items-center h-5">
<input
type="checkbox"
class="focus:ring-indigo-500 h-6 w-6 text-indigo-600 border-gray-300 rounded cursor-pointer"
/>
</div>
<div class="ml-3 text-sm w-full p-2 cursor-pointer">
<label class="font-medium text-gray-700 cursor-pointer">
{{ todo.name }}
</label>
</div>
</div>
<div class="flex items-center px-2 py-2 text-sm font-medium rounded-md">
<button>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
aria-hidden="true"
class="lex-shrink-0 h-5 w-5"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
/>
</svg>
</button>
</div>
</div>
Creating a Todo
Let's implement the functionality to create a todo and update the state after creating a todo in the database.
Open app.vue
and paste below code block to complete the functionality to create a todo.
const handleAddTodo = async () => {
try {
const { data, errors } = await altogic.db.model("todo").create({
name: todoInput.value,
});
if (errors) throw errors;
todoInput.value = "";
todos.value.unshift(data);
} catch (errorList) {
alert(errorList?.items[0].message);
}
};
<form @submit.prevent="handleAddTodo">
<div class="relative">
<input
placeholder="Add Todo"
class="w-full rounded-md border-gray-200 py-2.5 pr-10 pl-2 shadow-sm sm:text-sm border-2 border-dashed"
/>
<span class="absolute inset-y-0 right-0 grid w-10 place-content-center">
<button type="submit">
<span class="sr-only">Submit</span>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
aria-hidden="true"
id="send-icon"
class="w-7 h-7 text-gray-500"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M13 9l3 3m0 0l-3 3m3-3H8m13 0a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
</button>
</span>
</div>
</form>
Changing Todo Status
Let's implement the functionality to change the status of the todo and update the state after changing the status of the todo in the database.
So open app.vue
and paste below code block to complete the functionality to change the status of the todo.
const handleChangeStatus = async (todoId, newStatus) => {
try {
const { data: updatedTodo, errors } = await altogic.db
.model("todo")
.object(todoId)
.update({
isCompleted: newStatus,
});
if (errors) throw errors;
todos.value = todos.value.map((todo) =>
todo._id === todoId ? updatedTodo : todo
);
} catch (errorList) {
alert(errorList?.items[0].message);
}
};
<div class="flex items-center h-5">
<input
type="checkbox"
class="focus:ring-indigo-500 h-6 w-6 text-indigo-600 border-gray-300 rounded cursor-pointer"
@change="handleChangeStatus(todo._id, !todo.isCompleted)"
:checked="todo.isCompleted"
/>
</div>
<div
class="ml-3 text-sm w-full p-2 cursor-pointer"
@click="handleChangeStatus(todo._id, !todo.isCompleted)"
>
<label class="font-medium text-gray-700 cursor-pointer">
{{ todo.name }}
</label>
</div>
Deleting the Todo
The last thing we need to do is to implement the functionality to delete the todo and update the state after deleting the todo in the database.
So open app.vue
and paste below code block to complete the functionality to delete the todo.
const handleDeleteTodo = async (todoId) => {
try {
const { errors } = await altogic.db.model("todo").object(todoId).delete();
if (errors) throw errors;
todos.value = todos.value.filter((todo) => todo._id !== todoId);
} catch (errorList) {
alert(errorList?.items[0].message);
}
};
<button @click="handleDeleteTodo(todo._id)">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
aria-hidden="true"
class="lex-shrink-0 h-5 w-5"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
/>
</svg>
</button>
Congratulations!✨
You have successfully created a todo app with Nuxtjs and Altogic.
Enhancing User Experience
Let's add some features to improve the user experience of our todo app. E.g., We can show the completed todos below the list and strike out to improve the user experience.
Let's add the sort function in altogic client library to sorting.
const { data: todosFromDb, errors } = await altogic.db
.model("todo")
.sort("updatedAt", "desc")
.sort("isCompleted", "asc")
.page(1)
.limit(100)
.get();
Let's our variable by using the sort function in javascript so that the sorting is not broken when the state changes. So let's add line-through class to cross out completed todos.
const sortedTodos = computed(() =>
todos.value.sort((a, b) =>
a.isCompleted === b.isCompleted ? 0 : a.isCompleted ? 1 : -1
)
);
<div
v-for="todo in sortedTodos"
:key="todo._id"
class="flex items-center justify-between mt-2"
>
<div class="relative flex items-center">
<div class="flex items-center h-5">
<input
type="checkbox"
class="focus:ring-indigo-500 h-6 w-6 text-indigo-600 border-gray-300 rounded cursor-pointer"
@change="handleChangeStatus(todo._id, !todo.isCompleted)"
:checked="todo.isCompleted"
/>
</div>
<div
class="ml-3 text-sm w-full p-2 cursor-pointer"
@click="handleChangeStatus(todo._id, !todo.isCompleted)"
>
<label
class="font-medium text-gray-700 cursor-pointer"
v-bind:class="{ 'line-through': todo.isCompleted }"
>
{{ todo.name }}
</label>
</div>
</div>
<div class="flex items-center px-2 py-2 text-sm font-medium rounded-md">
<button @click="handleDeleteTodo(todo._id)">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
aria-hidden="true"
class="lex-shrink-0 h-5 w-5"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
/>
</svg>
</button>
</div>
</div>
Strategies for Optimizing Performance
If you want to add a search feature to your to-do application, you can add an index to the searched field with Altogic.
Let's open the Altogic designer and click on the name field of the todo model and select Indexed and Searchable properties and save them.

Conclusion
In this tutorial, we have learned how to create a todo app with Altogic. We have learned how to create a model, add fields, and create a todo app with Altogic. We have also learned how to add sorting feature to our todo app.
You can check out the source code of this tutorial.
You can access the demo of this tutorial.
If you want to access a more comprehensive example with features such as private todo creation, searching todo, inviting users, authentication, and real-time. You can check out Online Todo App or if you want to see more examples with Altogic, you can check out the showcase.