diff --git a/src/routes/docs/tutorials/nuxt/+layout.svelte b/src/routes/docs/tutorials/nuxt/+layout.svelte
new file mode 100644
index 0000000000..fb9fb3980f
--- /dev/null
+++ b/src/routes/docs/tutorials/nuxt/+layout.svelte
@@ -0,0 +1,10 @@
+
+
+
diff --git a/src/routes/docs/tutorials/nuxt/+layout.ts b/src/routes/docs/tutorials/nuxt/+layout.ts
new file mode 100644
index 0000000000..c8884f46b8
--- /dev/null
+++ b/src/routes/docs/tutorials/nuxt/+layout.ts
@@ -0,0 +1,11 @@
+import type { LayoutLoad } from './$types';
+
+export const load: LayoutLoad = ({ url }) => {
+ const tutorials = import.meta.glob('./**/*.markdoc', {
+ eager: true
+ });
+ return {
+ tutorials,
+ pathname: url.pathname
+ };
+};
diff --git a/src/routes/docs/tutorials/nuxt/+page.ts b/src/routes/docs/tutorials/nuxt/+page.ts
new file mode 100644
index 0000000000..fa071eee0a
--- /dev/null
+++ b/src/routes/docs/tutorials/nuxt/+page.ts
@@ -0,0 +1,6 @@
+import { redirect } from '@sveltejs/kit';
+import type { PageLoad } from './$types';
+
+export const load: PageLoad = async () => {
+ throw redirect(303, '/docs/tutorials/nuxt/step-1');
+};
diff --git a/src/routes/docs/tutorials/nuxt/step-1/+page.markdoc b/src/routes/docs/tutorials/nuxt/step-1/+page.markdoc
new file mode 100644
index 0000000000..7b0e25069f
--- /dev/null
+++ b/src/routes/docs/tutorials/nuxt/step-1/+page.markdoc
@@ -0,0 +1,35 @@
+---
+layout: tutorial
+title: Build an ideas tracker with Nuxt
+description: Learn to build an idea tracker app with Appwrite and Nuxt with authentication, databases and collections, queries, pagination, and file storage.
+step: 1
+difficulty: beginner
+readtime: 15
+back: /docs
+---
+
+**Idea tracker**: an app to track all the side project ideas that you'll start, but probably never finish.
+In this tutorial, you will build Idea tracker with Appwrite and Nuxt.
+
+{% only_dark %}
+
+{% /only_dark %}
+{% only_light %}
+
+{% /only_light %}
+
+# Concepts {% #concepts %}
+
+This tutorial will introduce the following concepts:
+
+1. Setting up your first project
+2. Authentication
+3. Navigation
+4. Databases and collections
+5. Queries
+
+
+# Prerequisites {% #prerequisites %}
+
+1. Basic knowledge of JavaScript.
+2. Have [Node.js](https://nodejs.org/en) and [NPM](https://www.npmjs.com/) installed on your computer.
diff --git a/src/routes/docs/tutorials/nuxt/step-2/+page.markdoc b/src/routes/docs/tutorials/nuxt/step-2/+page.markdoc
new file mode 100644
index 0000000000..1287aa4a52
--- /dev/null
+++ b/src/routes/docs/tutorials/nuxt/step-2/+page.markdoc
@@ -0,0 +1,152 @@
+---
+layout: tutorial
+title: Create app
+description: Create a Nuxt app project and integrate with Appwrite
+step: 2
+---
+
+# Create Nuxt project {% #create-nuxt-project %}
+
+Create a Nuxt app with the `npx init` command.
+The command will install all the necessary dependencies for you.
+
+```sh
+npx nuxi@latest init ideas-tracker
+```
+
+# Add dependencies {% #add-dependencies %}
+
+Once the project is created, change your current working directory and install the JavaScript Appwrite SDK.
+
+```sh
+cd ideas-tracker
+npm install appwrite
+```
+
+Open the file `nuxt.config.ts`and add links to the stylesheets from the `appwrite.io/pink` to import the design system.
+The design system is then ready to be used in all pages and components with auto-import, meaning that you don't have to add import statements to the scripts.
+
+```ts
+// [nuxt.config.ts]
+
+export default defineNuxtConfig({
+ app: {
+ head: {
+ link: [
+ { rel: "stylesheet", href: "https://unpkg.com/@appwrite.io/pink" },
+ {
+ rel: "stylesheet",
+ href: "https://unpkg.com/@appwrite.io/pink-icons",
+ },
+ ],
+ },
+ },
+ devtools: { enabled: true },
+});
+```
+
+You can start the development server to watch your app update in the browser as you make your changes.
+
+```sh
+npm run dev
+```
+
+# File structure {% #file-structure %}
+
+Nuxt relies on an opiniated directory structure to automate tasks and help organize the codebase.
+To take advantage of this we need to add the following directories:
+- `/components/` to keep our UI components in one place.
+ We will get back to it in [step 5](/docs/tutorials/nuxt/step-5)
+- `/composables/`for storing files handling global states and data fetching.
+ We will use it in [step 4](/docs/tutorials/nuxt/step-4)
+- `/layouts/` to store the page layouts
+- `/pages/` for the content pages.
+
+Run the following command to create these folders
+
+```sh
+mkdir components composables layouts pages
+```
+
+# Add layout {% #add-layout %}
+
+Go to the `layouts/` directory and add the file `default.vue`.
+Add the following code for the default layout.
+As you see it's nearly empty but it is needed for the automatic routing to work properly.
+
+```vue
+// [layouts/default.vue]
+
+
+
+
+
+
+
+
+```
+
+# Add home page {% #add-home-page %}
+
+Next, head over to the `pages`directory.
+This is where we will keep the content that will render on our pages in the web application.
+Each file you put in here will automatically become a route.
+Add the file `index.vue` with the following code.
+
+```vue
+// [pages/index.vue]
+
+
+
+
Hello, idea tracker!
+
+
+```
+
+This is what your directory should look like after adding the new directories and files:
+
+```
+[repository tree]
+
+├── .nuxt/
+├── components/
+├── composables/
+├── layouts/
+│ └── default.vue
+├── pages/
+│ ├── index.vue
+├── public/
+│ └── /favicon.ico
+├── server/
+│ └── /tsconfig.json
+├── .gitignore
+├── app.vue
+├── nuxt.config.ts
+├── package-lock.json
+├── package.json
+├── README.md
+└── tsconfig.json
+```
+
+# Render page {% #render-page %}
+
+If you run the development server now, it will still render the Nuxt Welcome page.
+We need to tell our app to use the files we just created instead.
+Open `app.vue`in the root directory and replace the content with the following code.
+Your page will now be up and running.
+
+```vue
+// [app.vue]
+
+
+
+
+
+
+
+
+```
diff --git a/src/routes/docs/tutorials/nuxt/step-3/+page.markdoc b/src/routes/docs/tutorials/nuxt/step-3/+page.markdoc
new file mode 100644
index 0000000000..89e25fbf4b
--- /dev/null
+++ b/src/routes/docs/tutorials/nuxt/step-3/+page.markdoc
@@ -0,0 +1,71 @@
+---
+layout: tutorial
+title: Set up Appwrite
+description: Import and configure a project with Appwrite Cloud.
+step: 3
+---
+
+# Create project {% #create-project %}
+
+Head to the [Appwrite Console](https://cloud.appwrite.io/console).
+
+{% only_dark %}
+
+{% /only_dark %}
+{% only_light %}
+
+{% /only_light %}
+
+If this is your first time using Appwrite, create an account and create your first project.
+
+Then, under **Add a platform**, add a **Web app**.
+The **Hostname** should be localhost.
+
+{% only_dark %}
+
+{% /only_dark %}
+{% only_light %}
+
+{% /only_light %}
+
+You can skip the optional steps.
+
+# Secrets
+
+To connect to Appwrite in our app, we'll need to use sensitive information.
+We keep the secrets by using environment variables for the endpoint and project id.
+Your project id is located in the **Settings** page in the Appwrite console.
+
+{% only_dark %}
+
+{% /only_dark %}
+{% only_light %}
+
+{% /only_light %}
+
+Add a `.env` file to the root directory and add the following code to it, replacing `YOUR_PROJECT_ID` with your project id.
+
+```
+VITE_APPWRITE_ENDPOINT="https://cloud.appwrite.io/v1"
+VITE_APPWRITE_PROJECT="YOUR_PROJECT_ID"
+```
+
+# Initialize Appwrite SDK {% #init-sdk %}
+
+Create a new file `appwrite.js` for the Appwrite related code.
+Only one instance of the `Client()` class should be created per app.
+Add the following code to it.
+
+```js
+import { Client, Databases, Account } from "appwrite";
+
+const url = import.meta.env.VITE_APPWRITE_ENDPOINT;
+const project = import.meta.env.VITE_APPWRITE_PROJECT;
+
+const client = new Client();
+
+client.setEndpoint(url).setProject(project);
+
+export const account = new Account(client);
+export const database = new Databases(client);
+```
diff --git a/src/routes/docs/tutorials/nuxt/step-4/+page.markdoc b/src/routes/docs/tutorials/nuxt/step-4/+page.markdoc
new file mode 100644
index 0000000000..7086a69149
--- /dev/null
+++ b/src/routes/docs/tutorials/nuxt/step-4/+page.markdoc
@@ -0,0 +1,175 @@
+---
+layout: tutorial
+title: Add authentication
+description: Add authentication to your Nuxt application using Appwrite Web SDK
+step: 4
+---
+
+For our ideas tracker app, we want any visitor to be able to read the ideas that are stored.
+On the other hand, we don't want the page spammed with just about anything from anyone just stopping by.
+To prevent that, or at least making it a bit more difficult, editing ideas will be available for logged in users only.
+With a login function, we can differentiate between users and decide which users have access to which content.
+
+We will build a page with a simple login form and store its related logic in a `useUserSession` composable so it can be reused, starting with the composable.
+
+## User session composable {% #user-session-composable %}
+
+There are a few standard functions involved in handling a user session that is added to the composable.
+The user needs to be able to register to an account, login to the account and logout from it.
+
+We are using Appwrite as a backend to handle the user details, so we need to connect to Appwrite by importing the configurations from step 3.
+The response from these interactions will be stored as references to get more information about the user in our app.
+
+In your `composable` directory, create the file `useUserSession.js` and add the following code.
+Then you can call the `useUserSession()` function in the pages and components to use the functionality.
+
+```js
+[composable/useUserSession.js]
+
+import { ID } from "appwrite";
+import { ref } from "vue";
+import { account } from "/appwrite";
+
+const current = ref(null) //Reference to current user object
+const isLoggedIn = ref(null) //Reference to check user status
+
+export const useUserSession = () => {
+ const register = async (email, password) => {
+ await account.create(ID.unique(), email, password); // Register new user in Appwrite
+ await login(email, password); // Login registered user
+ };
+
+ const login = async (email, password) => {
+ const authUser = await account.createEmailSession(email, password); // Open user session in Appwrite
+ current.value = authUser; // Pass user data to current ref
+ isLoggedIn.value = true; // Set ref to true
+ navigateTo("/");
+ };
+
+ const logout = async () => {
+ await account.deleteSession("current"); // Delete Appwrite user session
+ current.value = null; // Clear current ref
+ isLoggedIn.value = false; // Set ref to false
+ navigateTo("/");
+ };
+
+ return {
+ current,
+ isLoggedIn,
+ login,
+ logout,
+ register,
+ };
+};
+
+```
+# Login page {% #login-page %}
+
+To get the user input we will build a simple form with the logic from the `useUserSession()` composable.
+The form will have two input fields, one for the user's email-address and one for the password.
+Underneath will be two buttons for logging in or registering the user.
+
+Create a new file in the `pages` directory called `login.vue`.
+This will not only create a new page, it will also add the route `/login` to the url.
+In step 5 we will add a loginbutton that will redirect us to this page.
+Add the following code to build the form.
+
+```vue
+// [pages/login.vue]
+
+
+
+
+
Login/Register
+
+
+
+
+
+
+```
+
+Go to the browser and add `/login` to the url to check out the new page.
diff --git a/src/routes/docs/tutorials/nuxt/step-5/+page.markdoc b/src/routes/docs/tutorials/nuxt/step-5/+page.markdoc
new file mode 100644
index 0000000000..d554de7480
--- /dev/null
+++ b/src/routes/docs/tutorials/nuxt/step-5/+page.markdoc
@@ -0,0 +1,70 @@
+---
+layout: tutorial
+title: Add navigation
+description: Add navigation to your app.
+step: 5
+---
+
+To help our users navigate the app we want it to have a navigation bar that's visible on all pages.
+We will once again use the `useUserSession()` composable for information about the current user.
+
+With this piece of information we will show a login button when no user is logged in and a logout button when one is.
+We will also put the user's e-mail address next to the logout button.
+
+From the `components` directory, create the file `navbar.vue` and add the code below.
+
+```vue
+// [components/navbar.vue]
+
+
+
+
+
+
+
+
+
+
+```
+
+Open `app.vue` from the root directory and add the navigation bar.
+
+```vue
+// [app.vue]
+
+
+
+
+
+
+
+
+```
+
+Have a look in the browser at both the main page and the login page to test the new functionality.
diff --git a/src/routes/docs/tutorials/nuxt/step-6/+page.markdoc b/src/routes/docs/tutorials/nuxt/step-6/+page.markdoc
new file mode 100644
index 0000000000..52f746e70b
--- /dev/null
+++ b/src/routes/docs/tutorials/nuxt/step-6/+page.markdoc
@@ -0,0 +1,98 @@
+---
+layout: tutorial
+title: Add database
+description: Add databases and queries for ideas in your Nuxt project.
+step: 6
+---
+
+In Appwrite, data is stored as a collection of documents. Create a collection in the [Appwrite Console](https://cloud.appwrite.io/) to store the ideas.
+
+{% only_dark %}
+
+{% /only_dark %}
+{% only_light %}
+
+{% /only_light %}
+
+Create a new collection with the following attributes:
+| Field | Type | Required |
+|-------------|--------|----------|
+| userId | String | Yes |
+| title | String | Yes |
+| description | String | No |
+
+Change the collection's permissions in the settings to give access.
+First, add the role **Any** and check the **Read** box.
+Next, add a **Users** role and give them access to **create**, **update** and **delete** by checking those boxes.
+
+# Secrets
+
+Just like when we set up the connection to Appwrite in [step 2](/docs/tutorials/nuxt/step-2), we need to keep the variables with the collection id secret.
+Open the `.env` file and add your database id and your collection id to it.
+
+```
+VITE_IDEAS_DATABASE_ID="YOUR_DATABASE_ID"
+VITE_IDEAS_COLLECTION_ID="YOUR_COLLECTION_ID"
+```
+
+# Query methods {% #query-methods %}
+
+Now that we have a collection in the database to hold ideas, we can connect to it from our app.
+Our users should be able to read, add and remove ideas.
+We will add a new composable, `useIdeas`, to handle this functionality.
+
+Create a new file in the composables directory, `useIdeas.js` and add the following code.
+
+```js
+// [composables/useIdeas.js]
+
+import { ID, Query } from "appwrite";
+import { database } from "~/appwrite";
+import { ref } from "vue";
+
+const ideasDatabaseId = import.meta.env.VITE_IDEAS_DATABASE_ID;
+const ideasCollectionId = import.meta.env.VITE_IDEAS_COLLECTION_ID;
+
+const current = ref(null); //Reference for the fetched data
+
+export const useIdeas = () => {
+
+ // Fetch the 10 most recent ideas from the database
+ // Add the list to the current reference object
+ const init = async () => {
+ const response = await database.listDocuments(
+ ideasDatabaseId,
+ ideasCollectionId,
+ [Query.orderDesc("$createdAt"), Query.limit(10)]
+ );
+ current.value = response.documents;
+ };
+
+ // Add new idea to the database,
+ // Change the value of the current object
+ const add = async (idea) => {
+ const response = await database.createDocument(
+ ideasDatabaseId,
+ ideasCollectionId,
+ ID.unique(),
+ idea
+ );
+ current.value = [response, ...current.value].slice(0, 10);
+ };
+
+ const remove = async (id) => {
+ await database.deleteDocument(ideasDatabaseId, ideasCollectionId, id);
+ await init(); //Refetch ideas to ensure we have 10 items
+ };
+
+ return {
+ add,
+ current,
+ init,
+ remove,
+ };
+};
+
+```
+
+Now we can call the `useIdeas()` composable from the home page.
diff --git a/src/routes/docs/tutorials/nuxt/step-7/+page.markdoc b/src/routes/docs/tutorials/nuxt/step-7/+page.markdoc
new file mode 100644
index 0000000000..87fbbbe4e4
--- /dev/null
+++ b/src/routes/docs/tutorials/nuxt/step-7/+page.markdoc
@@ -0,0 +1,222 @@
+---
+layout: tutorial
+title: Ideas page
+description: Add ideas from Appwrite database in your app.
+step: 7
+---
+
+With the methods in the `useIdeas`composable we can get some ideas to the home page for the users to interact with.
+We will use it in a form component so the logged in users can add their ideas, and in a list component to render the ten most recent ideas.
+We start with building the form.
+
+# Idea form {% #idea-form %}
+
+On the home page, the logged in users should be able to add their ideas to the Appwrite database.
+The form need a text field for filling in the title, a textarea for the description and a submit button.
+
+From the `components` directory, add the file `ÌdeasForm.vue` and add the following code.
+
+```vue
+// [components/IdeasForm.vue]
+
+
+
+
+
Submit Idea
+
+
+
+
+
+
+
+```
+
+Next, add the component to the page `pages/index.vue` by auto-importing it in the ``tag.
+In doing that, we need to take a moment to think about how we want to display the form to the users.
+Since it should only be shown to logged in user, we need to wrap it in a ``that renders conditionally when the `isLoggedIn` reference in the `useUserSession` is true.
+If the requirement is not met, we show a paragraph with some information to the user instead.
+
+Add the following code to the `index.vue`page to conditionally render the form and information paragraph.
+
+Overwrite the contents of `pages/index.vue` with the following code.
+
+```vue
+// [pages/index.vue]
+
+
+
+
+
+
+
+
+
+
+
+
+ Please login to submit an idea.
+
+
+
+
+
+
+
+
+
+
+````
+
+# Ideas list {% #ideas-list %}
+Now that we can get some ideas to show, we go on to build the component for the list of ideas.
+
+Once again, we need to take a moment to think about how this component should work.
+First of all, the ideas should be visible for the users before any interaction has taken place on the page.
+To catch that moment in time when the page loads, we call our `init()` function, that fetches the ideas in Appwrite, from the built-in `onMounted` function.
+
+Second, it's likely that a user will want to delete one of their ideas from the database.
+We help them do that by adding a delete button in the top right corner of the idea list item, but only on the ideas added by the user itself.
+
+Add the file `IdeasList`from the `componenents` directory and insert the following code:
+
+```vue
+[componenents/IdeasList.vue]
+
+
+
+
+
Latest Ideas
+
+
+
+
{{ idea.title }}
+
{{ idea.description }}
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+Return to the file `pages/index.vue` once more to import the list of ideas.
+This component should be visible to all users, so no conditional rendering neeeds to be handled.
+
+```vue
+// [pages/index.vue]
+
+
+
+
+
+
+
+
+
+
+
+````
+
+Congratulations!
+You now have an ideas tracker built with Nuxt and Appwrite to use locally.
diff --git a/src/routes/docs/tutorials/nuxt/step-8/+page.markdoc b/src/routes/docs/tutorials/nuxt/step-8/+page.markdoc
new file mode 100644
index 0000000000..59d8e21475
--- /dev/null
+++ b/src/routes/docs/tutorials/nuxt/step-8/+page.markdoc
@@ -0,0 +1,11 @@
+---
+layout: tutorial
+title: Next steps
+description: View your Nuxt app built on Appwrite Cloud.
+step: 8
+---
+
+# Test your project {% #test-project %}
+Run your project with `npm run dev -- --open --port 3000` and open [http://localhost:3000](http://localhost:3000) in your browser.
+
+Head to the [Appwrite Console](https://cloud.appwrite.io/console) to see the new users and follow their interactions.