{"id":13534027,"url":"https://github.com/PineappleIOnic/appwrite-svelte","last_synced_at":"2025-04-01T22:31:08.912Z","repository":{"id":119413793,"uuid":"293563287","full_name":"PineappleIOnic/appwrite-svelte","owner":"PineappleIOnic","description":"Appwrite + Svelte = ❤️","archived":false,"fork":false,"pushed_at":"2020-09-09T00:44:19.000Z","size":45,"stargazers_count":7,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-31T07:34:05.603Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PineappleIOnic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-09-07T15:20:10.000Z","updated_at":"2024-09-26T14:19:49.000Z","dependencies_parsed_at":null,"dependency_job_id":"a32f122a-feb2-4990-9781-c7d1793c42fb","html_url":"https://github.com/PineappleIOnic/appwrite-svelte","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PineappleIOnic%2Fappwrite-svelte","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PineappleIOnic%2Fappwrite-svelte/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PineappleIOnic%2Fappwrite-svelte/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PineappleIOnic%2Fappwrite-svelte/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PineappleIOnic","download_url":"https://codeload.github.com/PineappleIOnic/appwrite-svelte/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246720476,"owners_count":20822911,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T07:01:25.518Z","updated_at":"2025-04-01T22:31:08.627Z","avatar_url":"https://github.com/PineappleIOnic.png","language":"JavaScript","funding_links":[],"categories":["Showcase (Built with Appwrite 📣)"],"sub_categories":["Svelte"],"readme":"# Appwrite + Svelte = ❤️\n\nThis example is to showcase [Appwrite's JS API](https://github.com/appwrite/sdk-for-js) with [Svelte](https://svelte.dev/) by creating a simple login/register page.\n\n## Prerequisites\n\n - A Recent Version of NodeJS\n - NPM (Feel free to use Yarn if you want to, just switch out the NPM Commands for their Yarn counterparts)\n - [A locally running appwrite instance](https://appwrite.io/docs/installation).\n\n## Getting Started\nTo get started quickly we will use degit to create the foundation for our project.\n```bash\nnpx degit sveltejs/template appwrite-svelte\ncd appwrite-svelte\nnpm install\n```\nThis will create a Svelte project in the `appwrite-svelte` folder relative to where the commands was run aswell as install any dependencies.\n\nWhile we are in the CLI we will install the Appwrite JS API by running:\n````bash\nnpm install appwrite\n````\nand finally, we will launch the svelte development server with:\n```bash\nnpm run dev\n```\nThis should launch a server on `localhost:5000` with Live Reload\n\n## Introducing the Appwrite SDK\nWith this boilerplate we can now initialise the Appwrite SDK in the project before working on the login page. Doing this is simple go ahead and open up `src/main.js`and underneath `import App from './App.svelte';` add:\n```js\nimport 'appwrite';\nconst appwrite = new window.Appwrite();  // Used for compatibility with a \u003cscript\u003e imported appwrite installation\nappwrite\n  .setEndpoint('http://localhost/v1')  // Set only when using self-hosted solution\n  .setProject('ProjectID');\n```\nWhat this does is import the Appwrite JS SDK and then initialises it with the Endpoint and ProjectID, make sure to replace `projectID` with the projectID that you created in appwrite. This will give us a `appwrite` object able to use the SDK methods we need.\n\nOne more thing we want to do is pass this appwrite object though props to `src/App.svelte` we can do this by finding:\n```js\nconst app =  new App({\n  target: document.body,\n  props:  {\n    name:  'world'\n  }\n});\n```\nand adding `appwrite: appwrite` to the props object and removing the name prop so it looks like this:\n```js\nconst app =  new App({\n  target: document.body,\n  props:  {\n    appwrite: appwrite\n  }\n});\n```\nThis means that the appwrite object is now accesible in `src/App.svelte` through a prop.\n\n## Creating the Login Page Logic\nCreating the Login Page is easy, go ahead and navigate to `src/App.svelte`  and remove all code within it, as we will be replacing this with our login form code with this removed we will move onto creating the logic behind this.\n\nFirst we want to start working on the script powering this, add the following to the top of `src/App.svelte`\n```svelte\n\u003cscript\u003e\n\texport let appwrite\n\timport { onMount } from 'svelte'\n\n\tlet username = '' // These will store the change in inputs for the login process\n\tlet password = ''\n\tlet error = false\n\tlet loading = false\n\tlet page = false\n\tlet userprofile = false\n\n\tconst logout = () =\u003e {\n\t\tuserprofile = false;\n\t\tappwrite.account.deleteSession('current');\n\t}\n\n\tconst getUserdata = async () =\u003e {\n\t\ttry {\n\t\t\tconst response = await appwrite.account.get();\n\t\t     \t\tloading =  false;\n\t\t\tuserprofile = response;\n\t\t} catch(err) {\n\t\t\tif (err == 'Error: Unauthorized') return;\n\t\t\terror = err;\n\t\t}\n\t}\n\t\n\tonMount(getUserdata);\n\n\tconst login = async (event) =\u003e {\n\t\tif (loading) return; // If still processing previous request then don't start a new one\n\t\ttry {\n\t\t\terror = false;\n\t\t\tloading = true;\n\t\t\tconst response = await appwrite.account.createSession(\n\t\t\t\tevent.target.email.value, \n\t\t\t\tevent.target.password.value\n\t\t\t);\n\t\t\tgetUserdata();\n\t\t} catch(error) {\n\t\t\tloading = false;\n\t\t\terror =  'Invalid Credentials';\n\t\t\tconsole.error(error);\n\t\t}\n\t}\n\u003c/script\u003e\n```\n\nSo, let's explain this script. First we grab the appwrite prop from the parent by using `export let appwrite` without this we won't be able to run API Calls, We then setup some variables to store various data we will use later. Including the username, passsword and a few other variables.\n\nThe login function which will be called on form submit will do the following:\n\n 1. Check that a previous request is not being processed using the loading variable, if it is then another request isn't started.\n 2. Sets error to false, this is used later to tell the user if something is wrong for example the appwrite server could not be reached or the username or password was incorrect.\n 3. Then the request is started, this is a promise so we use .then to process the result and .catch if something goes wrong.\n 4. If everything is successful then we stop the loading and get the userdata.\n 5. If an error occours we handle it and show a error to the user.\n\nWe also use onMount() to check if the user is already logged in on page load.\n\n## Creating the Login Page design\nWith the logic in place we can now start working on the login pages design including the form, add the following code below the `\u003cscript\u003e` you just added and not within it.\n\n```svelte\n\u003cmain\u003e\n  \u003cdiv class=\"loginCore\"\u003e\n    {#if !userprofile}\n      {#if !page}\n        \u003cdiv class=\"loginPage\"\u003e\n          \u003ch1\u003eLogin\u003c/h1\u003e\n          {#if error}\n            \u003cp class=\"error\"\u003e{error}\u003c/p\u003e\n          {/if}\n          \u003cform on:submit|preventDefault={login}\u003e\n            \u003cinput id=\"email\" required placeholder=\"Email\"\u003e\n            \u003cinput type=\"password\" id=\"password\" required placeholder=\"Password\"\u003e\n            \u003cbutton type=\"submit\" disabled={loading}\u003e{loading ? 'Please Wait' : 'Login'}\u003c/button\u003e\n          \u003c/form\u003e\n        \u003c/div\u003e\n      {:else}\n        \u003cdiv class=\"loginPage\"\u003e\n          \u003ch1\u003eRegister\u003c/h1\u003e\n          {#if error}\n            \u003cp class=\"error\"\u003e{error}\u003c/p\u003e\n          {/if}\n          \u003c!-- Create Registration code here --\u003e\n        \u003c/div\u003e\n      {/if}\n      \u003cp\u003e\n        {page ? 'Got an account?' : \"Haven't got an account?\"}\n        \u003cbr\u003e\n        \u003cspan on:click={() =\u003e page = !page}\u003e{page ? 'Login' : 'Sign Up'}\u003c/span\u003e\n      \u003c/p\u003e\n    {:else}\n      \u003cdiv class=\"loggedIn\"\u003e\n        \u003ch2\u003eLogged In!\u003c/h2\u003e\n        \u003ch1\u003e{userprofile.name}\u003c/h1\u003e\n        \u003cp\u003e{userprofile.email}\u003c/p\u003e\n        \u003cp\u003eID: {userprofile.$id}\u003c/p\u003e\n        \u003cbutton on:click={logout}\u003eLogout\u003c/button\u003e\n      \u003c/div\u003e\n    {/if}\n  \u003c/div\u003e\n\u003c/main\u003e\n```\n### Code Explanation\n(If you already know Svelte and understand this you can skip this section)\n\nThis weird type of HTML is Svelte's own superset of HTML which allows for JS to be embedded to create amazing web apps. I'll explain a few parts of this code.\n\u003cbr\u003e\n```svelte\n{#if !page}\n```\nThis is a condition statement for Svelte and allows us to add or remove elements based off conditions. This one for example is used to tell if we want to see the register or sign up page.\n\u003cbr\u003e\n\n```svelte\n\u003cp class=\"error\"\u003e{error}\u003c/p\u003e\n```\n`{}`in Svelte is similar to React's JSX Implementation and allows us to show variables from JS or run JS within the HTML. This one is used to display the error but later in the code you will see that I use this with a `?` operator to change text based off a variable.\n\u003cbr\u003e\n\n```svelte\n\u003cform on:submit|preventDefault={login}\u003e\n```\n`on:` is Svelte's way of binding events the `:preventDefault` section will preventDefault before running the login function when submit is called the event it sent to the previously written `login(event)` function.\n\n\n## Adding some style to your login page 😎\nIf you want you can style this yourself, but for those who don't want to add the following code below the `\u003c/main\u003e` section of your code, it's embedded CSS and will style your login form.\n\n\n```svelte\n\u003cstyle\u003e\n  :global(body) {\n    background: linear-gradient(90deg, rgba(209,0,176,1) 0%, rgba(0,249,255,1) 100%);\n  }\n  .loginCore {\n    position: absolute;\n    width: 300px;\n    background-color: white;\n    border-radius: 10px;\n    top: 50%;\n    left: 50%;\n    transform: translateX(-50%) translateY(-50%);\n    text-align: center;\n  }\n  .loginCore span {\n    color: rgb(0, 162, 255);\n  }\n  .loginCore span:hover {\n    cursor: pointer;\n  }\n  .loginPage input {\n    display: block;\n    margin: 0 auto;\n    margin-bottom: 20px;\n  }\n  .loggedIn {\n    padding-top: 30px;\n    padding-bottom: 30px;\n  }\n  .loggedIn h1 {\n    margin: 0;\n  }\n  .loggedIn h2 {\n    margin: 0;\n  }\n  .loggedIn p {\n    margin: 10px;\n  }\n  .error {\n    color: red;\n  }\n\u003c/style\u003e\n```\n## What next?\nCongratulations! You've just created a login page using Svelte and Appwrite! 🥳🥳🥳\n\nIf you noticed I left out the Register section for this tutorial and that was intentional. This is where I hand it off to you and allow you to use the techniques and ideas you used creating this project to add your own register page! The code to swich to the register page is already there you just need to add the form and create the functions to add it.\n\nAdd your Form code by replacing the section with:\n```\n\u003c!-- Create Registration code here --\u003e\n```\nGood Luck!\nIf you need any help feel free to join the [Discord](https://discord.gg/ZFwqr3S) or Refer to the [Appwrite Documentation](https://appwrite.io/docs).\nTIP: [Checkout account create documentation for the web API](https://appwrite.io/docs/client/account#create)\n\n(If you want to checkout the finished code is over on the [repository](https://github.com/PineappleIOnic/appwrite-svelte))\n\n## Bonus\nSome bonus tasks to improve the login page (To be added onto)\n\n - Add Regex Expressions for validating the Email\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPineappleIOnic%2Fappwrite-svelte","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FPineappleIOnic%2Fappwrite-svelte","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPineappleIOnic%2Fappwrite-svelte/lists"}