2022-12-01 11:25:45 +00:00
|
|
|
# Svelte + Appwrite = 🚀
|
|
|
|
|
2022-12-18 11:24:20 +00:00
|
|
|
## Appwrite svelte template
|
|
|
|
|
2022-12-01 11:25:45 +00:00
|
|
|
Blazing fast development with done backend and fully-prepared frontend.
|
|
|
|
|
2022-12-03 23:24:44 +00:00
|
|
|
CMS ready!
|
|
|
|
|
2022-12-02 16:52:06 +00:00
|
|
|
## Appwrite installation
|
|
|
|
|
|
|
|
[Appwrite installation](https://appwrite.io/docs/installation)
|
|
|
|
|
2022-12-23 21:11:18 +00:00
|
|
|
## Start
|
|
|
|
|
|
|
|
### Appwrite cli
|
|
|
|
|
|
|
|
```bash
|
|
|
|
npm install -g appwrite-cli
|
|
|
|
```
|
|
|
|
|
|
|
|
### Appwrite new project
|
|
|
|
|
|
|
|
```bash
|
|
|
|
appwrite init project
|
|
|
|
```
|
|
|
|
|
|
|
|
### Appwrite new collection
|
|
|
|
|
|
|
|
```bash
|
|
|
|
appwrite init collection
|
|
|
|
```
|
|
|
|
|
|
|
|
### Appwrite new function
|
|
|
|
|
|
|
|
```bash
|
|
|
|
appwrite init function
|
|
|
|
```
|
|
|
|
|
|
|
|
[Appwrite cli documentation](https://appwrite.io/docs/command-line)
|
|
|
|
|
|
|
|
## env
|
|
|
|
|
|
|
|
Edit `.env` file for config project id.
|
|
|
|
|
2022-12-02 16:52:43 +00:00
|
|
|
## Frontend included
|
2022-12-01 11:25:45 +00:00
|
|
|
|
|
|
|
* tailwind
|
|
|
|
* scss
|
2022-12-02 16:49:10 +00:00
|
|
|
* css reset
|
2022-12-01 11:25:45 +00:00
|
|
|
* typescript
|
|
|
|
* routing
|
2022-12-01 20:08:27 +00:00
|
|
|
* ready routes
|
2022-12-01 11:25:45 +00:00
|
|
|
* oauth
|
2022-12-08 15:09:46 +00:00
|
|
|
* files upload, download
|
2022-12-01 11:25:45 +00:00
|
|
|
* folder structure
|
|
|
|
* common components
|
|
|
|
* service worker
|
|
|
|
* path aliases
|
2022-12-01 20:08:27 +00:00
|
|
|
* database realtime subscribers
|
2022-12-08 23:43:04 +00:00
|
|
|
* database paginate, infinity scroll
|
2022-12-02 18:26:41 +00:00
|
|
|
* i18n
|
2022-12-03 23:24:44 +00:00
|
|
|
* cms
|
2022-12-04 14:58:31 +00:00
|
|
|
* cms forms components
|
2022-12-01 11:25:45 +00:00
|
|
|
* vite
|
|
|
|
* prettier
|
|
|
|
* editorconfig
|
2022-12-25 18:55:37 +00:00
|
|
|
* icons: [Feather icons](https://feathericons.com/)
|
2022-12-01 20:08:27 +00:00
|
|
|
|
|
|
|
## Database subscribers
|
|
|
|
|
2022-12-02 15:35:24 +00:00
|
|
|
```svelte
|
|
|
|
<script>
|
2023-01-02 16:16:44 +00:00
|
|
|
import { Collection } from '$lib/appwrite'
|
2022-12-03 09:30:26 +00:00
|
|
|
import { Query } from 'appwrite'
|
2022-12-02 15:35:24 +00:00
|
|
|
|
2022-12-03 09:30:26 +00:00
|
|
|
const collection = new Collection('[database-id]', '[collection-id]')
|
2023-01-02 16:16:44 +00:00
|
|
|
const [subscriber, loading] = collection.listDocuments(/* filters?: string[], offset?: number, limit?: number, orderType?: "ASC" | "DESC" */)
|
2022-12-06 21:10:53 +00:00
|
|
|
// listen changes (update, delete) in database and automatically rerender on change
|
2022-12-03 09:30:26 +00:00
|
|
|
// current data = [{ name: 'John', lastName: 'Doe' }, ...]
|
2022-12-06 21:10:53 +00:00
|
|
|
|
2023-01-02 16:16:44 +00:00
|
|
|
const [documentSubscriber, documentLoading] = collection.getDocument('[document-id]')
|
|
|
|
const [documentSubscriber, documentLoading] = collection.getDocument([Query.equal('name', 'John'), /*...*/])
|
|
|
|
// must be unique in collection, else throw error
|
|
|
|
|
|
|
|
const insertSubscriber = collection.listenInsert((item) => item.name !== 'John')
|
|
|
|
// listen changes (create/instert) in database and automatically rerender on change
|
|
|
|
// can be created with filter function
|
|
|
|
|
|
|
|
collection.createDocument({ name: 'John', lastname: 'Doe' }, [/* ...permissions */])
|
|
|
|
// creates a document in collection with data and permissions
|
|
|
|
|
|
|
|
collection.deleteDocument('[document-id]')
|
|
|
|
collection.deleteDocument($documentSubscriber)
|
|
|
|
// delete a document from collection by id or by the document
|
|
|
|
|
|
|
|
collection.updateDocument('[document-id]', { name: 'John', lastname: 'Doe' }, [/* ...permissions */])
|
|
|
|
collection.updateDocument($documentSubscriber, { name: 'John', lastname: 'Doe' }, [/* ...permissions */])
|
|
|
|
// update a document from collection by id or by the document
|
2022-12-06 21:10:53 +00:00
|
|
|
|
2022-12-07 12:07:13 +00:00
|
|
|
const [paginator, paginatorInitalLoading] = collection.createPaginate(10, [/* ...queries */])
|
2022-12-06 21:12:13 +00:00
|
|
|
// paginate the collection of documents with limit and automatically rerender on change
|
2022-12-07 12:07:13 +00:00
|
|
|
// paginator.next() makes the next request for items, paginator store automatically rerender on next load
|
2022-12-08 23:43:04 +00:00
|
|
|
|
|
|
|
const [scrollData, scrollDispatch] = collection.createInfinityScrollDispatcher(10, [/* ...queries */], { /* intersection observer options */ })
|
|
|
|
// load next data after scroll to anchor (scrollDispatch) element
|
2022-12-02 15:35:24 +00:00
|
|
|
</script>
|
|
|
|
|
2022-12-07 12:07:13 +00:00
|
|
|
<div>
|
2022-12-03 09:30:26 +00:00
|
|
|
{#if $loading}
|
2022-12-07 12:07:13 +00:00
|
|
|
<p>Loading data from database...</p>
|
2022-12-03 09:30:26 +00:00
|
|
|
{:else}
|
|
|
|
{#each [...$subscriber, ...$insertSubscriber] as item}
|
|
|
|
<p>{item.name}</p>
|
2022-12-02 15:35:24 +00:00
|
|
|
{/each}
|
2022-12-03 09:30:26 +00:00
|
|
|
{/if}
|
2022-12-07 12:07:13 +00:00
|
|
|
</div>
|
2022-12-08 23:43:04 +00:00
|
|
|
|
|
|
|
<!-- scroll dispatcher example -->
|
|
|
|
<div>
|
|
|
|
{#each $scrollData as item}
|
|
|
|
<p>{item.name}</p>
|
|
|
|
{/each}
|
|
|
|
<div use:scrollDispatch on:fetch={(e) => console.log(e) /* on every fetch from scroll dispatcher do some action */} />
|
|
|
|
</div>
|
2022-12-01 21:45:04 +00:00
|
|
|
```
|
|
|
|
|
2022-12-08 15:09:46 +00:00
|
|
|
## Files subscribers
|
|
|
|
|
|
|
|
```svelte
|
|
|
|
<script>
|
2023-01-02 16:16:44 +00:00
|
|
|
import { Bucket } from '$lib/appwrite'
|
2022-12-08 15:09:46 +00:00
|
|
|
import { Query } from 'appwrite'
|
|
|
|
|
|
|
|
const bucket = new Bucket('[bucket-id]')
|
2022-12-08 23:43:04 +00:00
|
|
|
const [files, loading] = bucket.createSubscriber([Query.limit(5) /*, ...queries */])
|
2022-12-08 15:09:46 +00:00
|
|
|
// listen changes (update, delete) in files and automatically rerender on change
|
|
|
|
|
|
|
|
const insertSubscriber = bucket.createObserver()
|
|
|
|
// listen changes (create) in files and automatically rerender on change
|
|
|
|
|
|
|
|
const [upload, dispatch] = storage.createUploadDispatcher(/* many files ? true : false, default = false */)
|
|
|
|
|
|
|
|
const [content, loading] = storage.getFileContent('6391f7c70ede82115575')
|
|
|
|
// get file content and automatically rerender on file update
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<div>
|
|
|
|
<input type="file" use:upload />
|
|
|
|
<button on:click={() => dispatch().then(uploadedFile => console.log(uploadedFile))}>Upload</button>
|
|
|
|
</div>
|
|
|
|
```
|
|
|
|
|
2022-12-01 21:45:04 +00:00
|
|
|
## Routing
|
|
|
|
|
2022-12-18 13:33:23 +00:00
|
|
|
Routes can be added in `__routes.svelte` file. Every route is fetched lazyly.
|
|
|
|
|
|
|
|
```svelte
|
|
|
|
<script lang="ts">
|
|
|
|
import Router from '$lib/router/Router.svelte'
|
|
|
|
|
|
|
|
import Layout from '$src/__layout.svelte'
|
|
|
|
import Loading from '$src/__loading.svelte'
|
|
|
|
import Error from '$src/__error.svelte'
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<Router
|
|
|
|
layout={Layout}
|
|
|
|
loading={Loading}
|
|
|
|
error={Error}
|
|
|
|
routes={[
|
|
|
|
{
|
|
|
|
path: '/',
|
|
|
|
component: () => import('$routes/index.svelte'),
|
2022-12-11 21:14:02 +00:00
|
|
|
},
|
2022-12-18 13:33:23 +00:00
|
|
|
{
|
|
|
|
path: '/oauth',
|
|
|
|
component: () => import('$routes/oauth/index.svelte'),
|
2022-12-11 21:14:02 +00:00
|
|
|
},
|
2022-12-18 13:33:23 +00:00
|
|
|
{
|
|
|
|
path: '/oauth/failure',
|
2022-12-11 21:14:02 +00:00
|
|
|
component: () => import('$routes/oauth/failure.svelte'),
|
|
|
|
},
|
2022-12-18 13:33:23 +00:00
|
|
|
{
|
|
|
|
path: '/oauth/success',
|
2022-12-11 21:14:02 +00:00
|
|
|
component: () => import('$routes/oauth/success.svelte'),
|
|
|
|
},
|
2022-12-18 13:33:23 +00:00
|
|
|
]}
|
|
|
|
/>
|
2022-12-01 21:45:04 +00:00
|
|
|
```
|
|
|
|
|
2022-12-08 15:09:46 +00:00
|
|
|
### Routes structure
|
|
|
|
|
|
|
|
`__layout.svelte` the default layout for every page
|
|
|
|
|
|
|
|
`__error.svelte` the error page (404 error)
|
|
|
|
|
2022-12-11 21:15:23 +00:00
|
|
|
`__loading.svelte` the default loading component
|
2022-12-11 21:14:02 +00:00
|
|
|
|
2022-12-18 13:33:23 +00:00
|
|
|
`__routes.svelte` the file includes all routes in application
|
2022-12-08 15:09:46 +00:00
|
|
|
|
2023-01-02 16:16:44 +00:00
|
|
|
## auth/user
|
2022-12-01 21:45:04 +00:00
|
|
|
|
|
|
|
```svelte
|
2022-12-03 09:30:26 +00:00
|
|
|
<script>
|
2023-01-02 16:16:44 +00:00
|
|
|
import { user } from '$lib/appwrite'
|
2022-12-03 09:30:26 +00:00
|
|
|
</script>
|
|
|
|
|
2022-12-07 12:07:13 +00:00
|
|
|
<div>
|
2023-01-02 16:16:44 +00:00
|
|
|
{#if $user}
|
|
|
|
user: {$user.name}
|
|
|
|
<button on:click={() => user.destroySession('current')}>Logout</button>
|
|
|
|
{:else}
|
|
|
|
<button on:click={() => user.createEmailSession('[email]', '[password]')}>Login</button>
|
|
|
|
{/if}
|
2022-12-07 12:07:13 +00:00
|
|
|
</div>
|
2022-12-01 21:45:04 +00:00
|
|
|
```
|
2022-12-03 09:30:26 +00:00
|
|
|
|
|
|
|
## i18n
|
|
|
|
|
|
|
|
Locale file `src/locales/en.json`
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"page": {
|
|
|
|
"home": {
|
2022-12-06 21:10:53 +00:00
|
|
|
"title": "Appwrite svelte rocket start 🚀"
|
2022-12-03 09:30:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
```svelte
|
|
|
|
<script>
|
|
|
|
import { _, locale, locales } from 'svelte-i18n'
|
|
|
|
</script>
|
|
|
|
|
2022-12-07 12:07:13 +00:00
|
|
|
<div>
|
2022-12-03 09:30:26 +00:00
|
|
|
<h1>{$_('page.home.title')}</h1>
|
|
|
|
|
|
|
|
<div>
|
|
|
|
<p>Change language:</p>
|
|
|
|
|
|
|
|
<select bind:value={$locale}>
|
|
|
|
{#each $locales as locale}
|
|
|
|
<option value={locale}>{locale}</option>
|
|
|
|
{/each}
|
|
|
|
</select>
|
|
|
|
</div>
|
2022-12-07 12:07:13 +00:00
|
|
|
</div>
|
2022-12-03 09:30:26 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
## path aliases
|
|
|
|
|
|
|
|
`$lib` = `src/lib`
|
2022-12-03 23:24:44 +00:00
|
|
|
|
2022-12-03 09:30:26 +00:00
|
|
|
`$root` = `/`
|
2022-12-03 23:24:44 +00:00
|
|
|
|
2022-12-03 09:30:26 +00:00
|
|
|
`$src` = `src`
|
2022-12-03 23:24:44 +00:00
|
|
|
|
2022-12-07 17:14:02 +00:00
|
|
|
`$routes` = `src/routes`
|
2022-12-07 12:07:13 +00:00
|
|
|
|
2022-12-03 23:24:44 +00:00
|
|
|
## commands
|
|
|
|
|
|
|
|
```bash
|
|
|
|
npm run dev
|
|
|
|
```
|
|
|
|
|
|
|
|
```bash
|
|
|
|
npm run build
|
|
|
|
```
|
|
|
|
|
|
|
|
```bash
|
|
|
|
npm run preview
|
|
|
|
```
|
|
|
|
|
|
|
|
```bash
|
|
|
|
npm run appwrite
|
|
|
|
```
|