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 %} +![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..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] + + +``` + +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 %} +![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 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 %} +![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 %} + +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] + + + + +``` + +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] +