diff --git a/src/routes/docs/tutorials/+page.svelte b/src/routes/docs/tutorials/+page.svelte index 8306de8aff..b5103f6376 100644 --- a/src/routes/docs/tutorials/+page.svelte +++ b/src/routes/docs/tutorials/+page.svelte @@ -61,6 +61,17 @@

+
  • + +
    +
    +

    + Learn Appwrite Auth, Databases, and more with Nuxt. +

    +
    +
  • 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..429f8698ab --- /dev/null +++ b/src/routes/docs/tutorials/nuxt/step-1/+page.markdoc @@ -0,0 +1,33 @@ +--- +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 +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 %} +![Create project screen](/images/docs/tutorials/dark/idea-tracker.png) +{% /only_dark %} +{% only_light %} +![Create project screen](/images/docs/tutorials/idea-tracker.png) +{% /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..d2d884fb00 --- /dev/null +++ b/src/routes/docs/tutorials/nuxt/step-2/+page.markdoc @@ -0,0 +1,107 @@ +--- +layout: tutorial +title: Build an ideas tracker with Nuxt +description: Learn to build an idea tracker app with Appwrite and Nuxt +step: 2 +--- + +# Create Nuxt project {% #create-nuxt-project %} + +Create a Nuxt app with the `npx init` command. + + +```sh +npx nuxi@latest init ideas-tracker +``` + +# Add dependencies {% #add-dependencies %} + +Install the JavaScript Appwrite SDK. + +```sh +npm install appwrite +``` + +You can start the development server to watch your app update in the browser as you make changes. + +```sh +npm run dev +``` + +# Pages and layouts for routing {% #pages-and-layout-for-routing %} + +In Nuxt, directories help organize the codebase and minimize boilerplate. The purpose is +making it easy to find and manage different aspect of your application. + +The files added to the `pages` directory will automatically become a route. Nuxt will look for a layout (can be more than one) to accompany a page +in the `layouts` directory. When these files have been created we can edit the `app.vue` file to render our pages. Now we will have a working app to verify our changes in the development server throughout the tutorial. +As an additional step, by adding [Appwrite's Pink Design system]('https://pink.appwrite.io/') we will also have a global layout system to help with the layout. + + +### 1. Add a page + +Create file `src/pages/index.vue` and add the following code: + +```vue + +``` + + +### 2. Add a default layout + + a file `src/layouts/default.vue` and insert the following code: + +```vue + + + +``` + +### 3. Edit app + +Go to `app.vue`, remove `NuxtWelcome`and insert `NuxtPage` wrapped in `NuxtLayout` + +```vue + +``` + + +### 4. Import layout + +Edit `nuxt.config.ts`to import Appwrite's design system to all pages and components. +The classes will be ready to use in the templates through auto-import. + +```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 }, +}); +``` 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..a21113c08e --- /dev/null +++ b/src/routes/docs/tutorials/nuxt/step-3/+page.markdoc @@ -0,0 +1,57 @@ +--- +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 %} +![Create project screen](/images/docs/quick-starts/dark/create-project.png) +{% /only_dark %} +{% only_light %} +![Create project screen](/images/docs/quick-starts/create-project.png) +{% /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 %} +![Add a platform](/images/docs/quick-starts/dark/add-platform.png) +{% /only_dark %} +{% only_light %} +![Add a platform](/images/docs/quick-starts/add-platform.png) +{% /only_light %} + +You can skip optional steps. + +# Initialize Appwrite SDK {% #init-sdk %} + +To use Appwrite in our Nuxt app, we'll need to find our project ID. It is located in the **Settings** page. + +{% only_dark %} +![Project settings screen](/images/docs/quick-starts/dark/project-id.png) +{% /only_dark %} +{% only_light %} +![Project settings screen](/images/docs/quick-starts/project-id.png) +{% /only_light %} + +Create a new file `src/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, replacing `` with your project ID. + +```js +import { Client, Databases, Account } from "appwrite"; + +const client = new Client(); +client + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject(""); // Replace with your project ID + +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..f9b628585f --- /dev/null +++ b/src/routes/docs/tutorials/nuxt/step-4/+page.markdoc @@ -0,0 +1,173 @@ +--- +layout: tutorial +title: Add authentication +description: Add authentication to your Nuxt application using Appwrite Web SDK +step: 4 +--- + +# Nuxt composables {% #nuxt-composables %} + +Composables is a pattern in Nuxt to manage logic related to data fetching and global state management. +Create a file `src/composables/useUserSession.js` in your composables directory. Add the following code: + +```js +import { ID } from 'appwrite' +import { ref } from 'vue' +import { account } from '/appwrite' + +const current = ref(null) +const isLoggedIn = ref(null) + +export const useUserSession = () => { + const register = async (email, password) => { + await account.create(ID.unique(), email, password) + await this.login(email, password) + } + + const login = async (email, password) => { + const authUser = await account.createEmailSession(email, password) + current.value = authUser + isLoggedIn.value = true + navigateTo('/ideas') + } + + const logout = async () => { + await account.deleteSession('current') + current.value = null + isLoggedIn.value = false + navigateTo('/') + } + return { + current, + isLoggedIn, + login, + logout, + register, + } +} +``` + +Now, we can import the `useUserSession` composable in any page or component and use it to login, logout, register a user or keep track of the current user. + +# Login page {% #login-page %} + +We will start with building a login page to handle the user sessions. + +Create a new file `src/pages/index.vue` and add the following code. + +```vue + + + + + +``` + +# User section on home page {% #user-section-on-home-page %} + +Finally, we will can modify the `src/pages/index.vue` to show a section for logged in users only: + +```vue + + + +``` 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..ba3fe48834 --- /dev/null +++ b/src/routes/docs/tutorials/nuxt/step-5/+page.markdoc @@ -0,0 +1,51 @@ +--- +layout: tutorial +title: Add navigation +description: Add navigation to your Nuxt applicating. +step: 5 +--- + +In our app we want to show a navigation bar. We will add it to the `app.vue` component and use the `useUserSession` composable to show either: +- a logout button if the user is logged in +- or a login button if the user is not logged in + +Update the `app.vue` file: + +```vue +template> +
    + + + + +
    + + + +``` 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..6fb1c440d8 --- /dev/null +++ b/src/routes/docs/tutorials/nuxt/step-6/+page.markdoc @@ -0,0 +1,72 @@ +--- +layout: tutorial +title: Add database +description: Add databases and queries for ideas in your Nuxt project. +step: 6 +--- +# Create collection {% #create-collection %} +In Appwrite, data is stored as a collection of documents. Create a collection in the [Appwrite Console](https://cloud.appwrite.io/) to store our ideas. + +{% only_dark %} +![Create project screen](/images/docs/tutorials/dark/idea-tracker-collection.png) +{% /only_dark %} +{% only_light %} +![Create project screen](/images/docs/tutorials/idea-tracker-collection.png) +{% /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 settings to give any role access to it. + +# Query methods {% #query-methods %} +Now that you have a collection to hold ideas, we can read and write to it from our app. +Create a new file in the composables directory, `src/composables/useIdeas.js` and add the following code to it. + +```js +import { ID, Query } from "appwrite"; +import { database } from "~/appwrite"; +import { ref } from "vue"; + +const IDEAS_DATABASE_ID = "YOUR_DATABASE_ID"; +const IDEAS_COLLECTION_ID = "YOUR_COLLECTION_ID"; + +const current = ref(null); + +export const useIdeas = () => { + const init = async () => { + const response = await database.listDocuments( + IDEAS_DATABASE_ID, + IDEAS_COLLECTION_ID, + [Query.orderDesc("$createdAt"), Query.limit(10)] + ); + current.value = response.documents; + }; + const add = async (idea) => { + const response = await database.createDocument( + IDEAS_DATABASE_ID, + IDEAS_COLLECTION_ID, + ID.unique(), + idea + ); + current.value = [response, ...current.value].slice(0, 10); + }; + + const remove = async (id) => { + await database.deleteDocument(IDEAS_DATABASE_ID, IDEAS_COLLECTION_ID, id); + current.value = current.value.filter((idea) => idea.$id !== id); + await init(); // Refetch ideas to ensure we have 10 items + }; + + return { + add, + current, + init, + remove, + }; +}; +``` 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..2e58bf2fec --- /dev/null +++ b/src/routes/docs/tutorials/nuxt/step-7/+page.markdoc @@ -0,0 +1,129 @@ +--- +layout: tutorial +title: Show ideas on home page +description: Add database queries using Appwrite in your Nuxt application. +step: 7 +--- + +# Show and add ideas {% #show-and-add-ideas %} + +Using the `useIdeas` composable we can now display the ideas on the page and add a form to submit new ideas. + +Overwrite the contents of `src/pages/index.vue` with the following: + +```vue +