Merge branch 'main' into doc-oauth-docs-change-same-site-cookie
@@ -9,3 +9,4 @@ PUBLIC_GROWTH_ENDPOINT=
|
||||
APPWRITE_DB_INIT_ID=
|
||||
APPWRITE_COL_INIT_ID=
|
||||
APPWRITE_API_KEY_INIT=
|
||||
SENTRY_AUTH_TOKEN=
|
||||
1
.github/workflows/production.yml
vendored
@@ -42,6 +42,7 @@ jobs:
|
||||
"APPWRITE_COL_INIT_ID=${{ secrets.APPWRITE_COL_INIT_ID }}"
|
||||
"APPWRITE_API_KEY_INIT=${{ secrets.APPWRITE_API_KEY_INIT }}"
|
||||
"GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}"
|
||||
"SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}"
|
||||
|
||||
deploy:
|
||||
needs: build
|
||||
|
||||
2
.github/workflows/staging.yml
vendored
@@ -1,6 +1,7 @@
|
||||
name: Staging deployment
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
@@ -43,6 +44,7 @@ jobs:
|
||||
"APPWRITE_COL_INIT_ID=${{ secrets.APPWRITE_COL_INIT_ID }}"
|
||||
"APPWRITE_API_KEY_INIT=${{ secrets.APPWRITE_API_KEY_INIT }}"
|
||||
"GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}"
|
||||
"SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}"
|
||||
|
||||
deploy:
|
||||
needs: build
|
||||
|
||||
23
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: Mark stale issues
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *" # Midnight Runtime
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-message: "This issue has been labeled as a 'question', indicating that it requires additional information from the requestor. It has been inactive for 7 days. If no further activity occurs, this issue will be closed in 14 days."
|
||||
stale-issue-label: "stale"
|
||||
days-before-stale: 7
|
||||
days-before-close: 14
|
||||
remove-stale-when-updated: true
|
||||
close-issue-message: "This issue has been closed due to inactivity. If you still require assistance, please provide the requested information."
|
||||
close-issue-reason: "not_planned"
|
||||
operations-per-run: 100
|
||||
only-labels: "question"
|
||||
17
.github/workflows/tests.yml
vendored
@@ -1,25 +1,22 @@
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ['**']
|
||||
pull_request:
|
||||
pull_request_target:
|
||||
branches: ['**']
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
- uses: pnpm/action-setup@v2
|
||||
name: Install pnpm
|
||||
with:
|
||||
version: 8
|
||||
run_install: false
|
||||
node-version: 20
|
||||
- name: Install pnpm
|
||||
run: corepack enable
|
||||
- name: Get pnpm store directory
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
4
.gitignore
vendored
@@ -12,4 +12,6 @@ vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
||||
package-lock.json
|
||||
.tool-versions
|
||||
.vscode
|
||||
.vscode
|
||||
# Sentry Config File
|
||||
.sentryclirc
|
||||
|
||||
47
CONTENT.md
@@ -71,6 +71,17 @@ Embed images using the `` syntax.
|
||||

|
||||
```
|
||||
|
||||
In most cases, we need images in both light and dark mode such as:
|
||||
|
||||
```md
|
||||
{% only_dark %}
|
||||

|
||||
{% /only_dark %}
|
||||
{% only_light %}
|
||||

|
||||
{% /only_light %}
|
||||
```
|
||||
|
||||
#### Code Blocks
|
||||
|
||||
Format code blocks using triple backticks (```).
|
||||
@@ -82,6 +93,8 @@ def hello_world():
|
||||
```
|
||||
</pre>
|
||||
|
||||
Remember to use a specific language label if the code is using an Appwrite SDK. Find the [list of available labels here](https://github.com/appwrite/website/blob/41bb6c71a8647016c88393003d3cf6c4edba1f76/src/lib/utils/references.ts#L26).
|
||||
|
||||
#### Inline Code
|
||||
|
||||
Highlight inline code with backticks (`) around the code snippet.
|
||||
@@ -94,6 +107,8 @@ Use the `print()` function to display text.
|
||||
|
||||
Use asterisks (\*) or underscores (\_) for emphasis and double asterisks or underscores for strong text.
|
||||
|
||||
**We use bold for representing text as seen on UI**. For example: "Click the button **Create new document**."
|
||||
|
||||
```md
|
||||
_Italic Text_ or _Italic Text_
|
||||
**Bold Text** or **Bold Text**
|
||||
@@ -110,6 +125,21 @@ Tables allow you to display structured data in your documentation. Use pipes (|)
|
||||
| Row 2, Col 1 | Row 2, Col 2 | Row 2, Col 3 |
|
||||
```
|
||||
|
||||
Alternatively, use markdoc tables.
|
||||
|
||||
```md
|
||||
{% table %}
|
||||
* Heading 1
|
||||
* Heading 2
|
||||
---
|
||||
* Row 1 Cell 1
|
||||
* Row 1 Cell 2
|
||||
---
|
||||
* Row 2 Cell 1
|
||||
* Row 2 cell 2
|
||||
{% /table %}
|
||||
```
|
||||
|
||||
#### Block Quotes
|
||||
|
||||
Block quotes are used to emphasize or highlight text. To create a block quote, use the > symbol at the beginning of the quoted text.
|
||||
@@ -156,7 +186,7 @@ print('test');
|
||||
</pre>
|
||||
|
||||
#### Sections
|
||||
|
||||
Use sections when there is a clear step-by-step format to a page. This is used mainly in journey pages and tutorials.
|
||||
```md
|
||||
{% section #featured-products-1 step=1 title="Title" %}
|
||||
Lorem ipsum dolor sit amet consectetur.
|
||||
@@ -213,7 +243,7 @@ Available sizes are `s`, `m`, `l` and `xl`. Default: `s`.
|
||||
```
|
||||
|
||||
#### Cards
|
||||
|
||||
We use cards when we reference a list of links for navigation
|
||||
{% cards %}
|
||||
{% cards_item href="/docs/quick-starts/react" title="React" %}
|
||||
Get started with Appwrite and React
|
||||
@@ -229,8 +259,19 @@ Get started with Appwrite and SvelteKit
|
||||
{% /cards_item %}
|
||||
{% /cards %}
|
||||
|
||||
#### Accordions
|
||||
#### Cards with icons
|
||||
We use cards when we reference a list of links for navigation, this variation has icons for extra hints visually.
|
||||
{% cards %}
|
||||
{% cards_item href="/docs/products/messaging/apns" title="APNS" icon="icon-apple" %}
|
||||
Configure APNs for push notification to Apple devices.
|
||||
{% /cards_item %}
|
||||
{% cards_item href="/docs/products/messaging/fcm" title="FCM" icon="web-icon-firebase" %}
|
||||
Configure FCM for push notification to Android and Apple devices.
|
||||
{% /cards_item %}
|
||||
{% /cards %}
|
||||
|
||||
#### Accordions
|
||||
Use accordions to reduce page size and collapse information that's not important when a reader is skilling the page.
|
||||
{% accordion %}
|
||||
{% accordion_item title="Team ID" %}
|
||||
|
||||
|
||||
@@ -25,9 +25,11 @@ Then, [clone the respository](https://docs.github.com/en/repositories/creating-a
|
||||
Alternatively, you can develop the website repo in your browser using [Code Spaces](https://github.com/features/codespaces) or [GitPod](https://www.gitpod.io/#https://github.com/appwrite/website).
|
||||
|
||||
## Development
|
||||
|
||||
The Appwrite website uses [PNPM](https://pnpm.io). Start by following their [installation](https://pnpm.io/installation) documentation.
|
||||
|
||||
Once you've cloned the Appwrite website repo, running the following command to install dependencies:
|
||||
|
||||
```sh
|
||||
pnpm i
|
||||
```
|
||||
@@ -58,11 +60,11 @@ doc-548-submit-a-pull-request-section-to-contribution-guide
|
||||
|
||||
When `TYPE` can be:
|
||||
|
||||
- **feat** - is a new feature
|
||||
- **doc** - documentation only changes
|
||||
- **cicd** - changes related to CI/CD system
|
||||
- **fix** - a bug fix
|
||||
- **refactor** - code change that neither fixes a bug nor adds a feature
|
||||
- **feat** - is a new feature
|
||||
- **doc** - documentation only changes
|
||||
- **cicd** - changes related to CI/CD system
|
||||
- **fix** - a bug fix
|
||||
- **refactor** - code change that neither fixes a bug nor adds a feature
|
||||
|
||||
**All PRs must include a commit message with a description of the changes made!**
|
||||
|
||||
@@ -71,20 +73,20 @@ Start by forking the project and use the `git clone` command to download the rep
|
||||
1. Before creating a new branch, pull the changes from upstream to make sure your default branch is up to date.
|
||||
|
||||
```
|
||||
$ git pull
|
||||
git pull
|
||||
```
|
||||
|
||||
2. Create a new branch from the default branch. For example `doc-548-submit-a-pull-request-section-to-contribution-guide`
|
||||
|
||||
```
|
||||
$ git checkout -b [name_of_your_new_branch]
|
||||
git checkout -b [name_of_your_new_branch]
|
||||
```
|
||||
|
||||
3. Work - commit - repeat ( be sure to be in your branch )
|
||||
4. Push changes to GitHub
|
||||
|
||||
```
|
||||
$ git push origin [name_of_your_new_branch]
|
||||
git push origin [name_of_your_new_branch]
|
||||
```
|
||||
|
||||
6. Submit your changes for review. If you go to your repository on GitHub, you'll see a `Compare & pull request` button. Click on that button.
|
||||
@@ -97,43 +99,5 @@ $ git push origin [name_of_your_new_branch]
|
||||
10. After approval, your PR will be merged.
|
||||
|
||||
## Documentation style
|
||||
For consistency the Appwrite documentation follows a strict set of style guidelines, so no matter who is writing the documentation,
|
||||
the tone and voice remains consistent.
|
||||
|
||||
### Headings
|
||||
- All titles, headings, buttons, and labels should be written in **sentence case**. If you're not sure what sentence case should look like, check [APA's style guide](https://apastyle.apa.org/style-grammar-guidelines/capitalization/sentence-case) or check with ChatGPT and other LLMs which reliably converts titles to sentence case.
|
||||
- All headings in a docs page begin with `# Heading` then `## Heading` and `### Heading`. Internally, they're converted to H2 to H4 tags.
|
||||
- All headings should have an ID label, for example `# Cool heading {% #cool-heading %}` the `#cool-heading` ID will be used to generate the table of contents and add links to the heading.
|
||||
- Prefer verbs over gerunds, for example, say "Create documents" not "Creating documents".
|
||||
|
||||
### Extended Markdoc components
|
||||
|
||||
Appwrite's documentation uses extended markdown syntax. You can find all of the available partials types in the [CONTENT.md file](./CONTENT.md).
|
||||
|
||||
### Screenshots
|
||||
- When contributing upload original screenshots. The Appwrite design team will edit the screenshot to be consistent with other screenshots in the docs.
|
||||
- Screnshots should be taken in a 1400 x 900 view port on 3x DPR in browser developer tools.
|
||||
- Use generic and sensible organization, project, and resource names. Avoid names like `test`, `demo`, or `sdlkfj`.
|
||||
- All screenshot should be take from a user named Walter O'Brien. You can change the name of your current user by going to your Appwrite Console and clicking the **top right profile icon** > **Your Account** > **Name**.
|
||||
|
||||
### Content consistency
|
||||
If you're contributing a **new piece of content**, always follow the closest example as an outline. For example, a new web quick start should use one of the existing web quick starts as example, with the same content and pages.
|
||||
|
||||
If you can't find a similar piece of content as example, the Appwrite team will request an ourline from you.
|
||||
|
||||
It should contain all the pages and headings with in them, maintainers may request clarification on headings.
|
||||
```md
|
||||
# page 1
|
||||
## heading a
|
||||
## heading b
|
||||
...
|
||||
# page 2
|
||||
## heading a
|
||||
## heading b
|
||||
...
|
||||
# page 3
|
||||
## heading a
|
||||
## heading b
|
||||
...
|
||||
...
|
||||
```
|
||||
When contributing to the Appwrite docs, follow the guide in [STYLE.md](./STYLE.md).
|
||||
|
||||
36
Dockerfile
@@ -1,5 +1,4 @@
|
||||
# Use an official Node runtime as a parent image
|
||||
FROM node:20-bullseye
|
||||
FROM node:20-bullseye as base
|
||||
|
||||
ARG PUBLIC_APPWRITE_COL_MESSAGES_ID
|
||||
ENV PUBLIC_APPWRITE_COL_MESSAGES_ID ${PUBLIC_APPWRITE_COL_MESSAGES_ID}
|
||||
@@ -34,23 +33,34 @@ ENV APPWRITE_API_KEY_INIT ${APPWRITE_API_KEY_INIT}
|
||||
ARG GITHUB_TOKEN
|
||||
ENV GITHUB_TOKEN ${GITHUB_TOKEN}
|
||||
|
||||
ARG SENTRY_AUTH_TOKEN
|
||||
ENV SENTRY_AUTH_TOKEN ${SENTRY_AUTH_TOKEN}
|
||||
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
|
||||
# Remove the node_modules folder to avoid wrong binaries
|
||||
RUN rm -rf node_modules
|
||||
|
||||
# Install fontconfig
|
||||
COPY ./local-fonts /usr/share/fonts
|
||||
RUN apt-get update; apt-get install -y fontconfig
|
||||
RUN fc-cache -f -v
|
||||
|
||||
COPY package.json package.json
|
||||
COPY pnpm-lock.yaml pnpm-lock.yaml
|
||||
RUN corepack enable
|
||||
|
||||
FROM base as build
|
||||
|
||||
COPY . .
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
|
||||
RUN NODE_OPTIONS=--max_old_space_size=8192 pnpm run build
|
||||
|
||||
EXPOSE 3000
|
||||
FROM base as final
|
||||
|
||||
# Install fontconfig
|
||||
COPY ./local-fonts /usr/share/fonts
|
||||
RUN apt-get update && \
|
||||
apt-get install -y fontconfig && \
|
||||
apt-get autoremove --purge && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
RUN fc-cache -f -v
|
||||
COPY --from=build /app/build/ build
|
||||
COPY --from=build /app/server/ server
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile --prod
|
||||
|
||||
CMD [ "node", "server/main.js"]
|
||||
323
STYLE.md
Normal file
@@ -0,0 +1,323 @@
|
||||
# Documentation contributing guide
|
||||
|
||||
Read this document carefully before making PRs to the Appwrite Website repo.
|
||||
|
||||
## What goes in docs?
|
||||
|
||||
The Appwrite documentation is meant to provide general guidance that's:
|
||||
|
||||
- Unopinionated
|
||||
- Focused on the correct use of Appwrite product
|
||||
- Includes examples for all relevant and applicable SDKs
|
||||
- Agnostic to the user's implementation and stack.
|
||||
|
||||
Examples of things not fit for docs, and better as a blog or video:
|
||||
|
||||
- General programming advice
|
||||
- Opinionated implementation patterns like MVVM, factory methods, etc.
|
||||
- Examples that only include a select subset of Appwrite SDKs.
|
||||
- Examples that do not work for all developers using Appwrite, but specific to Appwrite + technology.
|
||||
|
||||
Note that the tutorials and blogs available on the Appwrite blog and docs are meant for these types of information.
|
||||
|
||||
## Documentation structure
|
||||
|
||||
The Appwrite docs is split into sections, each with its intended purpose and content.
|
||||
|
||||
Appwrite's navigation increases in complexity from top down. We expect users to view links later in navigation later in their development journey.
|
||||
|
||||
Introduction Section:
|
||||
|
||||
- [Homes](https://appwrite.io/docs)
|
||||
- [Quick start](https://appwrite.io/docs/quick-start)
|
||||
- [Tutorial](https://appwrite.io/docs/tutorial)
|
||||
- [SDKs](https://appwrite.io/docs/sdks)
|
||||
- [API references](https://appwrite.io/docs/references)
|
||||
|
||||
Products section:
|
||||
|
||||
- [Auth](https://appwrite.io/docs/products/auth)
|
||||
- [Databases](https://appwrite.io/docs/products/databases)
|
||||
- [Functions](https://appwrite.io/docs/products/functions)
|
||||
- [Storage](https://appwrite.io/docs/products/storage)
|
||||
- [Messaging](https://appwrite.io/docs/products/messaging)
|
||||
- [AI](https://appwrite.io/docs/products/ai)
|
||||
|
||||
APIs section:
|
||||
|
||||
- [GraphQL](https://appwrite.io/docs/apis/graphql)
|
||||
- [REST](https://appwrite.io/docs/apis/rest)
|
||||
- [Realtime](https://appwrite.io/docs/apis/realtime)
|
||||
|
||||
Tooling section:
|
||||
|
||||
- [Command Line](https://appwrite.io/docs/command-line)
|
||||
- [Command center](https://appwrite.io/docs/tooling/command-center)
|
||||
- [Assistant](https://appwrite.io/docs/tooling/assistant)
|
||||
|
||||
Advanced section:
|
||||
|
||||
- [Platform](https://appwrite.io/docs/advanced/platform)
|
||||
- [Migrations](https://appwrite.io/docs/advanced/migrations)
|
||||
- [Self-hosting](https://appwrite.io/docs/advanced/self-hosting)
|
||||
- [Security](https://appwrite.io/docs/advanced/security)
|
||||
|
||||
Here's the intended purpose and structure of each section.
|
||||
|
||||
### Introduction
|
||||
|
||||
This section is focused on introducing what Appwrite is and giving examples to the user to understand both how to get started and how to perform canned tasks.
|
||||
Documentation here is focused on a **single flow** which means a single platform/framework + Appwrite.
|
||||
Content here is not specific to a specific product, but usually covers multiple Appwrite products.
|
||||
|
||||
- If your tutorial can be followed in about 15 minutes and fits on one page, write it under quick start
|
||||
- If you're writing a long piece of documentation that integrates Appwrite with another technology, with lots of details that's opinionated or isn't relevant for all use cases, write it under tutorial. This is similar to "cook book" at other organizations.
|
||||
- If you have information like helpers and methods that are only on SDKs but not the API, they go under SDK
|
||||
- API references are generated from source from the appwrite/appwrite repo
|
||||
|
||||
### Products
|
||||
|
||||
Each page covers an Appwrite product. These pages describe the expected behavior of the product and are **unopinionated** and **technology-agnostic**.
|
||||
Code examples should cover **all available SDKs**.
|
||||
|
||||
Each product page has three main sections
|
||||
|
||||
- Introduction
|
||||
- Overview - Describes at a high level, why you might need this product
|
||||
- Quick start - Shows the most basic and quickest example to make something happen with a product. Keep it really short.
|
||||
- Concept
|
||||
- These pages usually align with sections shown in the product in the Appwrite Console.
|
||||
- Focused on describing concepts a user should know, but not actions you might take.
|
||||
- Cover all the details
|
||||
- Journeys
|
||||
- These pages focus on common actions and work flows
|
||||
- Detailed examples that span many concepts
|
||||
- Like cookbook at other organizations' documentation.
|
||||
|
||||
### APIs section
|
||||
|
||||
Describes consuming APIs, which are a little more advanced, like using REST API directly or GraphQL directly.
|
||||
|
||||
### Tooling section
|
||||
|
||||
Describes tools that help you work with Appwrite, but are usually non-essential and not end-user facing.
|
||||
|
||||
### Advanced section
|
||||
|
||||
For information that's not used commonly during the development cycle.
|
||||
|
||||
- Platform: covers concepts that apply to the entire Appwrite Cloud platform, like API keys, rate limits, etc.
|
||||
- Migrations: covers migrations feature of Appwrite that helps you move data around.
|
||||
- Security: purely information about measures Appwrite use to ensure security of the platform and data.
|
||||
- Self-hosting: The Appwrite self-hosted platform is meant to behave identically to Cloud after being configured corrrectly. This section focuses on how to configure Appwrite self-hosted such that it behaves like Cloud.
|
||||
|
||||
## Documentation sources
|
||||
|
||||
The Appwrite docs are compiled from different repositories. Here are the significant touch points you need to know about.
|
||||
|
||||
[appwrite/website](https://github.com/appwrite/website):
|
||||
|
||||
- Tutorials
|
||||
- Quick starts
|
||||
- Product, API, Tooling and Advanced sections
|
||||
|
||||
[appwrite/appwrite](https://github.com/appwrite/appwrite):
|
||||
|
||||
- [API Reference](https://appwrite.io/docs/references) pages
|
||||
- API specification
|
||||
- API description
|
||||
- API endpoint description
|
||||
- API request parameters
|
||||
- API response model
|
||||
|
||||
[appwrite/sdk-generator](https://github.com/appwrite/sdk-generator):
|
||||
|
||||
- Generated examples
|
||||
|
||||
## Markdown Style guidelines
|
||||
|
||||
For consistency the Appwrite documentation follows a strict set of style guidelines, so no matter who is writing the documentation,
|
||||
the tone and voice remains consistent.
|
||||
|
||||
### Headings
|
||||
|
||||
- All titles, headings, buttons, and labels should be written in **sentence case**. If you're not sure what sentence case should look like, check [APA's style guide](https://apastyle.apa.org/style-grammar-guidelines/capitalization/sentence-case) or check with ChatGPT and other LLMs which reliably converts titles to sentence case.
|
||||
- All headings in a docs page begin with `# Heading` then `## Heading` and `### Heading`. Internally, they're converted to H2 to H4 tags.
|
||||
- All headings should have an ID label, for example `# Cool heading {% #cool-heading %}` the `#cool-heading` ID will be used to generate the table of contents and add links to the heading.
|
||||
- Prefer verbs over gerunds, for example, say "Create documents" not "Creating documents".
|
||||
|
||||
### Extended Markdoc components
|
||||
|
||||
Appwrite's documentation uses extended markdown syntax. You can find all of the available partials types in the [CONTENT.md file](./CONTENT.md).
|
||||
|
||||
### Screenshots
|
||||
|
||||
- When contributing upload original screenshots. The Appwrite design team will edit the screenshot to be consistent with other screenshots in the docs.
|
||||
- Screenshots must be 16:9
|
||||
- Screnshots should be taken in a 1400 x 900 view port on 3x DPR in browser developer tools.
|
||||
- Use generic and sensible organization, project, and resource names. Avoid names like `test`, `demo`, or `sdlkfj`.
|
||||
- All screenshot should be take from a user named Walter O'Brien. You can change the name of your current user by going to your Appwrite Console and clicking the **top right profile icon** > **Your Account** > **Name**.
|
||||
- Screenshots are stored in the `/images/docs/` folder, in a parent folder that is consistent with the path of the docs that reference the image.
|
||||
- All screenshots must be both dark and light mode, with `/path/` holding the lightmode version and `/path/dark/` holding the dark mode version.
|
||||
- Screenshots should be uploaded as un-edited original. Request help from the Appwrite design team to help you edit and refine your photos according to our guidelines.
|
||||
|
||||
```md
|
||||
{% only_dark %}
|
||||

|
||||
{% /only_dark %}
|
||||
{% only_light %}
|
||||

|
||||
{% /only_light %}
|
||||
```
|
||||
|
||||
### Content consistency
|
||||
|
||||
If you're contributing a **new piece of content**, always follow the closest example as an outline. For example, a new web quick start should use one of the existing web quick starts as example, with the same content and pages.
|
||||
|
||||
If you can't find a similar piece of content as example, the Appwrite team will request an outline from you.
|
||||
|
||||
It should contain all the pages and headings with in them, maintainers may request clarification on headings.
|
||||
|
||||
```md
|
||||
# page 1
|
||||
## heading a
|
||||
## heading b
|
||||
...
|
||||
# page 2
|
||||
## heading a
|
||||
## heading b
|
||||
...
|
||||
# page 3
|
||||
## heading a
|
||||
## heading b
|
||||
...
|
||||
...
|
||||
```
|
||||
|
||||
### Content splitting
|
||||
|
||||
Split content to make them easier to read. Split long sentences and long paragraphs such that key concepts can be obtained even when skimming through only first few words of paragraphs.
|
||||
|
||||
Split content such that each piece makes sense without reading dependents or explicitly link pre-requisit material.
|
||||
|
||||
## Common workflows
|
||||
|
||||
### Release prep
|
||||
|
||||
- [ ] Add new version to [src/lib/utils/references.ts](src/lib/utils/references.ts)
|
||||
- [ ] Point Cloud to new version in [src/routes/docs/references/[version]/[platform]/[service]/+page.server.ts](src/routes/docs/references/[version]/[platform]/[service]/+page.server.ts)
|
||||
- [ ] Update install command in [/workspaces/website/src/routes/docs/advanced/self-hosting/+page.markdoc](/workspaces/website/src/routes/docs/advanced/self-hosting/+page.markdoc)
|
||||
- [ ] Update events [src/partials/[product]-events.md](src/partials/)
|
||||
- [ ] Update response code [src/routes/docs/advanced/platform/response-codes/+page.markdoc](src/routes/docs/advanced/platform/response-codes/+page.markdoc)
|
||||
- [ ] Bump latest SDK versions in SDKs page, quick start, and tutorials
|
||||
- [ ] Create new sections for new products
|
||||
- [ ] Create new concept and journey pages for new features
|
||||
- [ ] Update docs for breaking changes
|
||||
|
||||
### Documenting a new API
|
||||
|
||||
- Add a new .md file describing the new API here: <https://github.com/appwrite/appwrite/tree/main/docs/references>
|
||||
- Add descriptions for methods and parameters in the controller code: <https://github.com/appwrite/appwrite/tree/main/app/controllers/api>
|
||||
- Check new response models have meaningful descriptions
|
||||
|
||||
### Adding a new quickstart
|
||||
|
||||
- Copy a quick start from the [src/routes/docs/quick-starts](src/routes/docs/quick-starts) folder.
|
||||
- Add a new entry and logo to [src/routes/docs/quick-starts/+page.svelte](src/routes/docs/quick-starts/+page.svelte)
|
||||
- If you need a new logo, contact the Appwrite team to add one to Pink design.
|
||||
- Update the content of your tutorial. Remember to update the front matter!
|
||||
- Try to be consistent in both the quickstart's content and format when compared to existing quick starts
|
||||
- Add the quick start to the footer and front page of Appwrite
|
||||
- Use sections for steps on your page
|
||||
|
||||
### Adding a new tutorial
|
||||
|
||||
- Copy a tutorial from the [src/routes/docs/tutorials](src/routes/docs/tutorials) folder.
|
||||
- Update the `+page.ts`'s redirect, for example, the Android tutorial has this: [src/routes/docs/tutorials/android/+page.ts](src/routes/docs/tutorials/android/+page.ts)
|
||||
- Update [src/routes/docs/tutorials/+page.svelte](src/routes/docs/tutorials/+page.svelte) and add your new tutorial
|
||||
- Update [src/routes/docs/tutorials/android/+layout.ts](src/routes/docs/tutorials/android/+layout.ts) and add your new tutorial
|
||||
- Add the content of your tutorial. Keep pages short, separated by a different distinct feature for each step.
|
||||
- If you need a new logo, contact the Appwrite team to add one to Pink design.
|
||||
- Add the tutorial to the footer and front page of Appwrite
|
||||
|
||||
## Language and diction
|
||||
|
||||
### Headings
|
||||
|
||||
Prefer simple nouns and root form verbs.
|
||||
|
||||
✅ Create screen (root verb, noun)
|
||||
✅ Authentication (noun)
|
||||
❌ Authenticating (present participle verb)
|
||||
❌ Create a new screen (too wordy)
|
||||
|
||||
Try your best to stick to simple headings, if it's not possible, don't worry and write a full heading if need be.
|
||||
|
||||
### Links
|
||||
|
||||
Avoid unclear [links](https://www.youtube.com/watch?v=dQw4w9WgXcQ) such as learn more [here](https://www.youtube.com/watch?v=dQw4w9WgXcQ).
|
||||
Readers will be unsure where a link may take them. Those using a screen reader will find it especially difficult.
|
||||
|
||||
✅ [Learn more about authentication](https://appwrite.io/docs/products/auth/email-password#login)
|
||||
❌ Learn more about authentication [here](https://www.youtube.com/watch?v=dQw4w9WgXcQ)
|
||||
|
||||
### Sentences
|
||||
|
||||
Use a directive that's straight to the point when providing an action a developer must perform.
|
||||
The action and verb always comes first, the explanation after.
|
||||
|
||||
✅ Create a new database.
|
||||
✅ Update a document so its permissions include your new users.
|
||||
❌ To allow access, update your permissions.
|
||||
❌ You can create a new database for each tenant.
|
||||
❌ Creating a new bucket lets you set different permissions for images uploaded by users.
|
||||
|
||||
The action always comes first and is in the beginning of the sentence, which makes important steps easier to follow.
|
||||
|
||||
If a step is more of a suggestion or is optional, you can intentially use another form to make it easier for users
|
||||
to skip and scan a document.
|
||||
|
||||
### Paragraphs
|
||||
|
||||
Like sentences, important information always comes first.
|
||||
This makes it easier to scan through the page.
|
||||
|
||||
✅ Clear, important information such as actions come first
|
||||
> Store secrets as environment variables in vaults by navigating to **settings** > **security** > **vault**. Your secrets should never be shared. You must ensure data privacy, sharing secrets can compromise security during development.
|
||||
|
||||
❌ Unclear, important information is in the middle of the paragraph
|
||||
> Security is important in development. That's why you should take care to protect secrets. Secrets should be safely stored as a environment variable in a vault. You can find vaults under **settings** > **security** > **vault**. Don't share this with anyone!
|
||||
|
||||
If there are multiple important actions or pieces of information, **break up the paragraph**.
|
||||
Even if your paragraph is just one or two sentences, shorter paragraphs are easier to scan.
|
||||
|
||||
### Diction
|
||||
|
||||
If you're unsure about which word to use to describe a concept, you shuold look for precedence in the following order.
|
||||
|
||||
1. Appwrite docs
|
||||
2. Appwrite Console
|
||||
3. Appwrite API specs
|
||||
4. Existing blogs
|
||||
5. Follow other products when possible.
|
||||
6. If all other avenues are explored, propose a new term. Clearly outline in your PR and come to agreement with the Appwrite team.
|
||||
|
||||
### Page structure
|
||||
|
||||
Quick starts, tutorials, product docs, and other pages should stick very close to existing examples.
|
||||
This applies to tone, structure, and content. Unless no exisitng examples of a page type exist,
|
||||
or a page needs to be sufficiently different from existing pages, follow exisitng examples.
|
||||
|
||||
If you are proposing a new type of page, discuss an outline in your PR and ask for the Appwrite team's review.
|
||||
|
||||
## Code snippets
|
||||
|
||||
For quick starts and tutorials, a developer must be able to follow code examples from beginning to end
|
||||
easily, and the code example is expected to be runnable and complete.
|
||||
|
||||
This means, you need to include imports, dependencies, and all parts needed to arrive at a functional example.
|
||||
|
||||
For concept and journey product pages, still try your best to have complete examples, unless:
|
||||
|
||||
1. The example will become opinionated. We avoid opinionated implementation and choices in product pages. Keep them in blogs, quick starts, and tutorials.
|
||||
2. The example cannot be given in a complete form cleanly. For example, many of the Messaging services's examples cannot be given in complete form because the boiler plate and set up is complex and documented in Android/Swift documentation.
|
||||
@@ -1,5 +1,3 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:2.9
|
||||
@@ -12,11 +10,14 @@ services:
|
||||
- --entrypoints.websecure.address=:443
|
||||
- --providers.docker.constraints=Label(`traefik.constraint-label-stack`,`homepage`)
|
||||
- --accesslog=true
|
||||
labels:
|
||||
- traefik.http.routers.traefik.middlewares=traefik-compress
|
||||
- traefik.http.middlewares.traefik-compress.compress=true
|
||||
ports:
|
||||
- 80:80
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- /letsencrypt:/letsencrypt
|
||||
# - /letsencrypt:/letsencrypt
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
networks:
|
||||
- homepage
|
||||
@@ -25,23 +26,33 @@ services:
|
||||
image: homepage-dev
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
- PUBLIC_APPWRITE_PROJECT_INIT_ID=$PUBLIC_APPWRITE_PROJECT_INIT_ID
|
||||
- PUBLIC_APPWRITE_PROJECT_ID=$PUBLIC_APPWRITE_PROJECT_ID
|
||||
- PUBLIC_APPWRITE_DB_MAIN_ID=$PUBLIC_APPWRITE_DB_MAIN_ID
|
||||
- PUBLIC_APPWRITE_COL_THREADS_ID=$PUBLIC_APPWRITE_COL_THREADS_ID
|
||||
- PUBLIC_APPWRITE_COL_MESSAGES_ID=$PUBLIC_APPWRITE_COL_MESSAGES_ID
|
||||
- PUBLIC_APPWRITE_FN_TLDR_ID=$PUBLIC_APPWRITE_FN_TLDR_ID
|
||||
restart: always
|
||||
networks:
|
||||
- homepage
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.constraint-label-stack=homepage
|
||||
- traefik.docker.network=homepage
|
||||
- traefik.http.services.homepage.loadbalancer.server.port=3000
|
||||
- traefik.docker.network=appwrite
|
||||
- traefik.http.middlewares.appwrite_middlewares.compress=true
|
||||
- traefik.http.services.appwrite_service.loadbalancer.server.port=3000
|
||||
#http
|
||||
- traefik.http.routers.homepage.entrypoints=web
|
||||
- traefik.http.routers.homepage.rule=PathPrefix(`/`)
|
||||
- traefik.http.routers.homepage.service=homepage
|
||||
- traefik.http.routers.appwrite.entrypoints=web
|
||||
- traefik.http.routers.appwrite.rule=PathPrefix(`/`)
|
||||
- traefik.http.routers.appwrite.service=appwrite_service
|
||||
- traefik.http.routers.appwrite.middlewares=appwrite_middlewares
|
||||
# https
|
||||
- traefik.http.routers.homepage_secure.entrypoints=websecure
|
||||
- traefik.http.routers.homepage_secure.rule=PathPrefix(`/`)
|
||||
- traefik.http.routers.homepage_secure.service=homepage
|
||||
- traefik.http.routers.homepage_secure.tls=true
|
||||
|
||||
- traefik.http.routers.appwrite_secure.entrypoints=websecure
|
||||
- traefik.http.routers.appwrite_secure.rule=PathPrefix(`/`)
|
||||
- traefik.http.routers.appwrite_secure.service=appwrite_service
|
||||
- traefik.http.routers.appwrite_secure.tls=true
|
||||
- traefik.http.routers.appwrite_secure.middlewares=appwrite_middlewares
|
||||
|
||||
networks:
|
||||
homepage:
|
||||
@@ -57,6 +57,9 @@ services:
|
||||
- node.role == manager
|
||||
preferences:
|
||||
- spread: node.role == worker
|
||||
labels:
|
||||
- traefik.http.routers.traefik.middlewares=traefik-compress
|
||||
- traefik.http.middlewares.traefik-compress.compress=true
|
||||
|
||||
server:
|
||||
image: ghcr.io/appwrite/website:$_APP_VERSION
|
||||
@@ -84,17 +87,20 @@ services:
|
||||
- traefik.enable=true
|
||||
- traefik.docker.lbswarm=true
|
||||
- traefik.constraint-label-stack=appwrite
|
||||
- traefik.http.services.appwrite_api.loadbalancer.server.port=3000
|
||||
- traefik.http.services.appwrite_service.loadbalancer.server.port=3000
|
||||
- traefik.http.middlewares.appwrite_middlewares.compress=true
|
||||
#http
|
||||
- traefik.http.routers.appwrite.entrypoints=web
|
||||
- traefik.http.routers.appwrite.rule=Host(`$_APP_DOMAIN`) || Host(`www.$_APP_DOMAIN`)
|
||||
- traefik.http.routers.appwrite.service=appwrite_api
|
||||
- traefik.http.routers.appwrite.service=appwrite_service
|
||||
- traefik.http.routers.appwrite.middlewares=appwrite_middlewares
|
||||
# https
|
||||
- traefik.http.routers.appwrite_secure.entrypoints=websecure
|
||||
- traefik.http.routers.appwrite_secure.rule=Host(`$_APP_DOMAIN`) || Host(`www.$_APP_DOMAIN`)
|
||||
- traefik.http.routers.appwrite_secure.service=appwrite_api
|
||||
- traefik.http.routers.appwrite_secure.service=appwrite_service
|
||||
- traefik.http.routers.appwrite_secure.tls=true
|
||||
- traefik.http.routers.appwrite_secure.tls.certresolver=myresolver
|
||||
- traefik.http.routers.appwrite_secure.middlewares=appwrite_middlewares
|
||||
|
||||
janitor:
|
||||
image: appwrite/docker-janitor
|
||||
|
||||
@@ -58,6 +58,9 @@ services:
|
||||
- node.role == manager
|
||||
preferences:
|
||||
- spread: node.role == worker
|
||||
labels:
|
||||
- traefik.http.routers.traefik.middlewares=traefik-compress
|
||||
- traefik.http.middlewares.traefik-compress.compress=true
|
||||
|
||||
server:
|
||||
image: ghcr.io/appwrite/website:$_APP_VERSION
|
||||
@@ -85,17 +88,20 @@ services:
|
||||
- traefik.enable=true
|
||||
- traefik.docker.lbswarm=true
|
||||
- traefik.constraint-label-stack=appwrite
|
||||
- traefik.http.services.appwrite_api.loadbalancer.server.port=3000
|
||||
- traefik.http.services.appwrite_service.loadbalancer.server.port=3000
|
||||
- traefik.http.middlewares.appwrite_middlewares.compress=true
|
||||
#http
|
||||
- traefik.http.routers.appwrite.entrypoints=web
|
||||
- traefik.http.routers.appwrite.rule=Host(`$_APP_DOMAIN`) || Host(`www.$_APP_DOMAIN`)
|
||||
- traefik.http.routers.appwrite.service=appwrite_api
|
||||
- traefik.http.routers.appwrite.service=appwrite_service
|
||||
- traefik.http.routers.appwrite.middlewares=appwrite_middlewares
|
||||
# https
|
||||
- traefik.http.routers.appwrite_secure.entrypoints=websecure
|
||||
- traefik.http.routers.appwrite_secure.rule=Host(`$_APP_DOMAIN`) || Host(`www.$_APP_DOMAIN`)
|
||||
- traefik.http.routers.appwrite_secure.service=appwrite_api
|
||||
- traefik.http.routers.appwrite_secure.service=appwrite_service
|
||||
- traefik.http.routers.appwrite_secure.tls=true
|
||||
- traefik.http.routers.appwrite_secure.tls.certresolver=myresolver
|
||||
- traefik.http.routers.appwrite_secure.middlewares=appwrite_middlewares
|
||||
|
||||
janitor:
|
||||
image: appwrite/docker-janitor
|
||||
|
||||
67
package.json
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "website-svelte",
|
||||
"name": "appwrite-website",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
@@ -20,54 +20,55 @@
|
||||
"test:integration": "playwright test",
|
||||
"test:unit": "vitest"
|
||||
},
|
||||
"packageManager": "pnpm@8.15.6",
|
||||
"packageManager": "pnpm@9.4.0+sha512.f549b8a52c9d2b8536762f99c0722205efc5af913e77835dbccc3b0b0b2ca9e7dc8022b78062c17291c48e88749c70ce88eb5a74f1fa8c4bf5e18bb46c8bd83a",
|
||||
"dependencies": {
|
||||
"compression": "^1.7.4",
|
||||
"express": "^4.18.2"
|
||||
"@sentry/sveltekit": "^8.12.0",
|
||||
"h3": "^1.12.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@appwrite.io/console": "^0.6.1",
|
||||
"@appwrite.io/pink": "0.16",
|
||||
"@appwrite.io/pink-icons": "0.16",
|
||||
"@appwrite.io/console": "^0.6.2",
|
||||
"@appwrite.io/pink": "~0.16.0",
|
||||
"@appwrite.io/pink-icons": "~0.16.0",
|
||||
"@appwrite.io/repo": "github:appwrite/appwrite#main",
|
||||
"@melt-ui/pp": "^0.3.0",
|
||||
"@melt-ui/svelte": "^0.74.3",
|
||||
"@playwright/test": "^1.42.0",
|
||||
"@internationalized/date": "3.5.0",
|
||||
"@melt-ui/pp": "^0.3.2",
|
||||
"@melt-ui/svelte": "^0.74.4",
|
||||
"@playwright/test": "^1.44.1",
|
||||
"@sveltejs/adapter-node": "^4.0.1",
|
||||
"@sveltejs/enhanced-img": "^0.1.8",
|
||||
"@sveltejs/kit": "^2.5.2",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.2",
|
||||
"@sveltejs/enhanced-img": "^0.1.9",
|
||||
"@sveltejs/kit": "^2.5.17",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.1.1",
|
||||
"@types/compression": "^1.7.5",
|
||||
"@types/glob": "^8.1.0",
|
||||
"@types/markdown-it": "^13.0.7",
|
||||
"@types/markdown-it": "^13.0.8",
|
||||
"@types/morgan": "^1.9.9",
|
||||
"@typescript-eslint/eslint-plugin": "^7.1.0",
|
||||
"@typescript-eslint/parser": "^7.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^7.13.1",
|
||||
"@typescript-eslint/parser": "^7.13.1",
|
||||
"dequal": "^2.0.3",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^8.10.0",
|
||||
"eslint-plugin-svelte": "^2.35.1",
|
||||
"eslint-plugin-svelte": "^2.40.0",
|
||||
"highlight.js": "^11.9.0",
|
||||
"markdown-it": "^14.0.0",
|
||||
"markdown-it": "^14.1.0",
|
||||
"meilisearch": "^0.37.0",
|
||||
"motion": "^10.17.0",
|
||||
"node-html-parser": "^6.1.12",
|
||||
"motion": "^10.18.0",
|
||||
"node-html-parser": "^6.1.13",
|
||||
"openapi-types": "^12.1.3",
|
||||
"oslllo-svg-fixer": "^3.0.0",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-plugin-svelte": "^3.2.2",
|
||||
"sass": "^1.71.1",
|
||||
"sharp": "^0.33.2",
|
||||
"svelte": "^4.2.12",
|
||||
"svelte-check": "^3.6.5",
|
||||
"svelte-markdoc-preprocess": "^1.2.1",
|
||||
"prettier": "^3.3.2",
|
||||
"prettier-plugin-svelte": "^3.2.5",
|
||||
"sass": "^1.77.6",
|
||||
"sharp": "^0.33.4",
|
||||
"svelte": "^4.2.18",
|
||||
"svelte-check": "^3.8.1",
|
||||
"svelte-markdoc-preprocess": "^2.0.0",
|
||||
"svelte-markdown": "^0.4.1",
|
||||
"svgtofont": "^4.1.2",
|
||||
"tslib": "^2.6.2",
|
||||
"typescript": "^5.3.3",
|
||||
"vite": "^5.1.4",
|
||||
"svgtofont": "^4.2.1",
|
||||
"tslib": "^2.6.3",
|
||||
"typescript": "^5.5.2",
|
||||
"vite": "^5.3.1",
|
||||
"vite-plugin-dynamic-import": "^1.5.0",
|
||||
"vite-plugin-image-optimizer": "^1.1.7",
|
||||
"vitest": "^1.3.1"
|
||||
"vite-plugin-image-optimizer": "^1.1.8",
|
||||
"vitest": "^1.6.0"
|
||||
}
|
||||
}
|
||||
|
||||
10440
pnpm-lock.yaml
generated
@@ -1,16 +1,17 @@
|
||||
import express from 'express';
|
||||
import compression from 'compression'
|
||||
import { sitemap } from './sitemap.js'
|
||||
import { createApp, fromNodeMiddleware, toNodeListener } from 'h3';
|
||||
import { createServer } from 'node:http';
|
||||
import { handler } from '../build/handler.js';
|
||||
import { sitemap } from './sitemap.js';
|
||||
|
||||
async function main() {
|
||||
const app = express();
|
||||
app.use(compression());
|
||||
app.use(await sitemap());
|
||||
app.use(handler);
|
||||
app.listen(3000, () => {
|
||||
console.log('Listening on http://0.0.0.0:3000');
|
||||
const port = process.env.PORT || 3000;
|
||||
const app = createApp();
|
||||
app.use('/sitemap.xml', await sitemap());
|
||||
app.use(fromNodeMiddleware(handler));
|
||||
const server = createServer(toNodeListener(app)).listen(port);
|
||||
server.addListener('listening', () => {
|
||||
console.log(`Listening on http://0.0.0.0:${port}`);
|
||||
});
|
||||
}
|
||||
|
||||
main();
|
||||
main();
|
||||
|
||||
@@ -1,36 +1,43 @@
|
||||
import { createRequire } from 'node:module'
|
||||
import { createRequire } from 'node:module';
|
||||
import { defineEventHandler, setResponseHeader } from 'h3';
|
||||
|
||||
/**
|
||||
* @returns {Promise<import('express').RequestHandler>}
|
||||
* @returns {Promise<import('h3').EventHandler>}
|
||||
*/
|
||||
export async function sitemap() {
|
||||
console.info('Preparing Sitemap...');
|
||||
const manifest = await import('../build/server/manifest.js');
|
||||
const prerendered = manifest.prerendered;
|
||||
|
||||
const routes = [
|
||||
...prerendered,
|
||||
...collectThreads()
|
||||
];
|
||||
const file_route_extensions = ['.json', '.xml'];
|
||||
const routes = [...prerendered, ...collectThreads()].filter(
|
||||
(route) => !file_route_extensions.some((ext) => route.endsWith(ext))
|
||||
);
|
||||
console.info(`Sitemap loaded with ${routes.length} routes!`);
|
||||
|
||||
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
${routes.filter(route => !route.endsWith('.json')).map(route => `<url>
|
||||
${routes
|
||||
.map(
|
||||
(route) => `<url>
|
||||
<loc>https://appwrite.io${route}</loc>
|
||||
</url>
|
||||
`).join('')}
|
||||
`
|
||||
)
|
||||
.join('')}
|
||||
</urlset>`;
|
||||
|
||||
return async (req, res, next) => {
|
||||
if (req.url === '/sitemap.xml') {
|
||||
res.setHeader('Content-Type', 'application/xml');
|
||||
return res.send(sitemap);
|
||||
}
|
||||
next();
|
||||
}
|
||||
return defineEventHandler((event) => {
|
||||
setResponseHeader(event, 'Content-Type', 'application/xml');
|
||||
|
||||
return sitemap;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string[]}
|
||||
*/
|
||||
function collectThreads() {
|
||||
const threads = createRequire(import.meta.url)('../build/prerendered/threads/data.json');
|
||||
|
||||
return threads.map(id => `/threads/${id}`);
|
||||
}
|
||||
return threads.map((id) => `/threads/${id}`);
|
||||
}
|
||||
|
||||
29
src/hooks.client.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { dev } from '$app/environment';
|
||||
import { SENTRY_DSN } from '$lib/constants';
|
||||
import { handleErrorWithSentry, replayIntegration } from '@sentry/sveltekit';
|
||||
import * as Sentry from '@sentry/sveltekit';
|
||||
|
||||
Sentry.init({
|
||||
enabled: !dev,
|
||||
dsn: SENTRY_DSN,
|
||||
allowUrls: [/appwrite\.io/],
|
||||
tracesSampleRate: 1.0,
|
||||
|
||||
// This sets the sample rate to be 10%. You may want this to be 100% while
|
||||
// in development and sample at a lower rate in production
|
||||
replaysSessionSampleRate: 0,
|
||||
|
||||
// If the entire session is not sampled, use the below sample rate to sample
|
||||
// sessions when an error occurs.
|
||||
replaysOnErrorSampleRate: 1.0,
|
||||
|
||||
// If you don't want to use Session Replay, just remove the line below:
|
||||
integrations: [replayIntegration({
|
||||
maskAllInputs: true,
|
||||
maskAllText: false,
|
||||
blockAllMedia: false,
|
||||
})]
|
||||
});
|
||||
|
||||
// If you have a custom error handler, pass it to `handleErrorWithSentry`
|
||||
export const handleError = handleErrorWithSentry();
|
||||
@@ -1,7 +1,16 @@
|
||||
import * as Sentry from '@sentry/sveltekit';
|
||||
import type { Handle } from '@sveltejs/kit';
|
||||
import redirects from './redirects.json';
|
||||
import { sequence } from '@sveltejs/kit/hooks';
|
||||
import { BANNER_KEY } from '$lib/constants';
|
||||
import { BANNER_KEY, SENTRY_DSN } from '$lib/constants';
|
||||
import { dev } from '$app/environment';
|
||||
|
||||
Sentry.init({
|
||||
enabled: !dev,
|
||||
dsn: SENTRY_DSN,
|
||||
tracesSampleRate: 1,
|
||||
allowUrls: [/appwrite\.io/]
|
||||
})
|
||||
|
||||
const redirectMap = new Map(redirects.map(({ link, redirect }) => [link, redirect]));
|
||||
|
||||
@@ -26,4 +35,5 @@ const bannerRewriter: Handle = async ({ event, resolve }) => {
|
||||
return response;
|
||||
};
|
||||
|
||||
export const handle = sequence(redirecter, bannerRewriter);
|
||||
export const handle = sequence(Sentry.sentryHandle(), redirecter, bannerRewriter);
|
||||
export const handleError = Sentry.handleErrorWithSentry();
|
||||
@@ -1,4 +1 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M18 13.6935V17.3418H8.8811C6.22438 17.3418 3.90468 15.8745 2.66359 13.6935C2.48317 13.3765 2.32526 13.0438 2.1928 12.6985C1.93277 12.022 1.76932 11.296 1.71973 10.5384V9.55209C1.73049 9.38328 1.74746 9.21579 1.76964 9.05029C1.81499 8.71068 1.88351 8.37835 1.97356 8.05532C2.82542 4.99278 5.59535 2.74878 8.8811 2.74878C12.1668 2.74878 14.9365 4.99278 15.7883 8.05532H11.8892C11.2491 7.05702 10.1411 6.39703 8.8811 6.39703C7.62109 6.39703 6.51312 7.05702 5.873 8.05532C5.67789 8.35879 5.52651 8.69343 5.42733 9.05029C5.33924 9.3667 5.29226 9.70035 5.29226 10.0453C5.29226 11.091 5.72488 12.0336 6.4185 12.6985C7.06123 13.3158 7.92777 13.6935 8.8811 13.6935H18Z" fill="#E4E4E7"/>
|
||||
<path d="M18.0001 9.05029V12.6985H11.3438C12.0374 12.0336 12.47 11.091 12.47 10.0453C12.47 9.70034 12.423 9.3667 12.3349 9.05029H18.0001Z" fill="#E4E4E7"/>
|
||||
</svg>
|
||||
<svg width="18" height="17" viewBox="0 0 18 17" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M7.232 0.031 C 5.975 0.153,4.795 0.554,3.754 1.214 C 2.817 1.808,1.918 2.698,1.313 3.630 C 0.623 4.692,0.155 6.011,0.028 7.250 C -0.026 7.774,0.007 9.014,0.087 9.480 C 0.288 10.645,0.725 11.762,1.344 12.690 C 1.698 13.220,1.949 13.528,2.370 13.952 C 3.726 15.316,5.458 16.113,7.380 16.259 C 7.634 16.278,9.695 16.290,12.893 16.290 L 18.000 16.290 18.000 14.250 L 18.000 12.210 12.817 12.210 C 7.090 12.210,7.351 12.218,6.731 12.017 C 6.099 11.812,5.664 11.544,5.172 11.055 C 4.403 10.291,4.012 9.404,3.970 8.325 C 3.943 7.637,4.040 7.083,4.288 6.508 C 4.810 5.296,5.845 4.437,7.125 4.153 C 7.450 4.081,8.144 4.065,8.515 4.122 C 9.216 4.229,9.955 4.572,10.471 5.029 C 10.694 5.226,11.001 5.565,11.130 5.755 L 11.235 5.910 13.387 5.910 C 14.571 5.910,15.540 5.901,15.540 5.891 C 15.540 5.834,15.397 5.401,15.278 5.100 C 14.860 4.036,14.271 3.139,13.456 2.323 C 12.234 1.099,10.744 0.344,9.045 0.087 C 8.592 0.019,7.659 -0.010,7.232 0.031 M11.768 7.103 C 11.870 7.659,11.885 7.836,11.869 8.295 C 11.852 8.795,11.812 9.032,11.680 9.435 C 11.503 9.973,11.186 10.520,10.831 10.899 L 10.643 11.100 14.322 11.100 L 18.000 11.100 18.000 9.060 L 18.000 7.020 14.877 7.020 L 11.753 7.020 11.768 7.103 " fill="#414146" stroke="none" fill-rule="evenodd"></path></svg>
|
||||
|
Before Width: | Height: | Size: 946 B After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
6
src/icons/svg/appwrite.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg width="18" height="17" viewBox="0 0 18 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="appwrite">
|
||||
<path id="Vector" d="M18 12.2017V16.2689H7.91783C4.98048 16.2689 2.41575 14.6331 1.04357 12.2017C0.844087 11.8482 0.669498 11.4773 0.523046 11.0924C0.235551 10.3381 0.0548296 9.52877 0 8.68426V7.58463C0.0119038 7.39643 0.0306613 7.20971 0.0551903 7.02521C0.105331 6.64658 0.181082 6.2761 0.280641 5.91596C1.22248 2.50171 4.28501 0 7.91783 0C11.5506 0 14.6128 2.50171 15.5547 5.91596H11.2437C10.5359 4.80302 9.31093 4.06723 7.91783 4.06723C6.52472 4.06723 5.29971 4.80302 4.59198 5.91596C4.37627 6.25428 4.20889 6.62736 4.09923 7.02521C4.00184 7.37794 3.9499 7.74991 3.9499 8.13445C3.9499 9.30026 4.42821 10.3511 5.19511 11.0924C5.90573 11.7805 6.8638 12.2017 7.91783 12.2017H18Z" fill="#414146"/>
|
||||
<path id="Vector_2" d="M18.0001 7.02527V11.0925H10.6406C11.4075 10.3512 11.8858 9.30033 11.8858 8.13451C11.8858 7.74997 11.8339 7.37801 11.7365 7.02527H18.0001Z" fill="#414146"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1002 B |
@@ -3,6 +3,7 @@
|
||||
import { animation, createScrollHandler, scroll, type Animation } from '.';
|
||||
import { toScale, type Scale } from '$lib/utils/toScale';
|
||||
import { browser } from '$app/environment';
|
||||
import { GITHUB_STARS } from '$lib/constants';
|
||||
|
||||
const springOptions: SpringOptions = { stiffness: 58.78, mass: 1, damping: 17.14 };
|
||||
const animationOptions: AnimationListOptions = {
|
||||
@@ -184,7 +185,7 @@
|
||||
aria-label="GitHub"
|
||||
/>
|
||||
</div>
|
||||
<div class="web-title u-margin-block-start-auto">38k+ GitHub Stars</div>
|
||||
<div class="web-title u-margin-block-start-auto">{GITHUB_STARS}+ GitHub Stars</div>
|
||||
</a>
|
||||
|
||||
<a
|
||||
|
||||
@@ -35,9 +35,9 @@
|
||||
{ label: 'Auth', href: '/docs/products/auth' },
|
||||
{ label: 'Databases', href: '/docs/products/databases' },
|
||||
{ label: 'Functions', href: '/docs/products/functions' },
|
||||
{ label: 'Messaging', href: '/docs/products/messaging' },
|
||||
{ label: 'Messaging', href: '/products/messaging' },
|
||||
{ label: 'Storage', href: '/docs/products/storage' },
|
||||
{ label: 'Realtime', href: '/docs/apis/realtime' }
|
||||
{ label: 'Realtime', href: '/docs/apis/realtime' },
|
||||
],
|
||||
Learn: [
|
||||
{ label: 'Docs', href: '/docs' },
|
||||
@@ -46,6 +46,12 @@
|
||||
{ label: 'Threads', href: '/threads' },
|
||||
{ label: 'Blog', href: '/blog' },
|
||||
{ label: 'Changelog', href: '/changelog' },
|
||||
{
|
||||
label: 'Roadmap',
|
||||
href: 'https://github.com/orgs/appwrite/projects',
|
||||
target: '_blank',
|
||||
rel: 'noopener noreferrer'
|
||||
},
|
||||
{
|
||||
label: 'Source code',
|
||||
href: 'https://github.com/appwrite',
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<li class="web-strip-plans-item web-strip-plans-container-query">
|
||||
<div class="web-strip-plans-item-wrapper">
|
||||
<div class="web-strip-plans-plan">
|
||||
<h4 class="title web-description">Starter</h4>
|
||||
<h4 class="title web-description">Free</h4>
|
||||
<div class="web-title web-u-color-text-primary">$0</div>
|
||||
<div class="info web-caption-500" />
|
||||
</div>
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
<script lang="ts">
|
||||
export let selector = '#main';
|
||||
export let exclude: CreateTableOfContentsArgs['exclude'] = ['h1', 'h3', 'h4', 'h5', 'h6'];
|
||||
export let activeType: CreateTableOfContentsArgs['activeType'] = 'lowest';
|
||||
export let scrollOffset: CreateTableOfContentsArgs['scrollOffset'] = 120;
|
||||
export let activeType: CreateTableOfContentsArgs['activeType'] = 'highest';
|
||||
export let scrollOffset: CreateTableOfContentsArgs['scrollOffset'] = 0;
|
||||
|
||||
const toc = createTableOfContents({
|
||||
selector,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export const GITHUB_STARS = '40K';
|
||||
export const GITHUB_STARS = '41.9K';
|
||||
export const BANNER_KEY = 'discord-banner-01'; // Change key to force banner to show again
|
||||
export const SENTRY_DSN = 'https://27d41dc8bb67b596f137924ab8599e59@o1063647.ingest.us.sentry.io/4507497727000576'
|
||||
|
||||
/**
|
||||
* History:
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
import { addEventListener } from '@melt-ui/svelte/internal/helpers';
|
||||
import { onMount } from 'svelte';
|
||||
import { page } from '$app/stores';
|
||||
import { loggedIn } from '$lib/utils/console';
|
||||
|
||||
export let omitMainId = false;
|
||||
let theme: 'light' | 'dark' | null = 'dark';
|
||||
@@ -102,7 +103,7 @@
|
||||
{
|
||||
label: 'Changelog',
|
||||
href: '/changelog',
|
||||
showBadge: hasNewChangelog() && !$page.url.pathname.includes('/changelog')
|
||||
showBadge: hasNewChangelog?.() && !$page.url.pathname.includes('/changelog')
|
||||
},
|
||||
{
|
||||
label: 'Pricing',
|
||||
@@ -178,7 +179,6 @@
|
||||
class="web-main-header is-special-padding theme-{resolvedTheme} is-transparent"
|
||||
class:is-hidden={$isHeaderHidden}
|
||||
>
|
||||
|
||||
<div class="web-top-banner">
|
||||
<div class="web-top-banner-content web-u-color-text-primary">
|
||||
<a href="/discord" target="_blank" rel="noopener noreferrer">
|
||||
|
||||
29
src/lib/utils/withPrevious.test.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { describe, expect, test } from 'vitest';
|
||||
import { withPrevious } from './withPrevious';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
describe('withPrevious', () => {
|
||||
test('Should retain previous value (number)', () => {
|
||||
const { previous, ...store } = withPrevious(0);
|
||||
expect(get(previous)).toBe(0);
|
||||
expect(get(store)).toBe(0);
|
||||
store.set(1);
|
||||
expect(get(previous)).toBe(0);
|
||||
expect(get(store)).toBe(1);
|
||||
store.set(2);
|
||||
expect(get(previous)).toBe(1);
|
||||
expect(get(store)).toBe(2);
|
||||
});
|
||||
|
||||
test('Should retain previous value (array)', () => {
|
||||
const { previous, ...store } = withPrevious([0]);
|
||||
expect(get(previous)).toEqual([0]);
|
||||
expect(get(store)).toEqual([0]);
|
||||
store.set([1]);
|
||||
expect(get(previous)).toEqual([0]);
|
||||
expect(get(store)).toEqual([1]);
|
||||
store.set([2]);
|
||||
expect(get(previous)).toEqual([1]);
|
||||
expect(get(store)).toEqual([2]);
|
||||
});
|
||||
});
|
||||
24
src/lib/utils/withPrevious.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { readonly, writable } from 'svelte/store';
|
||||
|
||||
export function withPrevious<T>(initial: T) {
|
||||
const previous = writable(initial);
|
||||
const store = writable(initial);
|
||||
|
||||
const update: typeof store.update = (fn) => {
|
||||
store.update((current) => {
|
||||
previous.set(current);
|
||||
return fn(current);
|
||||
});
|
||||
};
|
||||
|
||||
const set: typeof store.set = (value) => {
|
||||
update(() => value);
|
||||
};
|
||||
|
||||
return {
|
||||
...store,
|
||||
previous: readonly(previous),
|
||||
set,
|
||||
update
|
||||
};
|
||||
}
|
||||
19
src/lib/utils/withRaf.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
export function withRaf(callback: () => void): void {
|
||||
let raf: number | null = null;
|
||||
|
||||
const loop = () => {
|
||||
callback();
|
||||
raf = requestAnimationFrame(loop);
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
raf = requestAnimationFrame(loop);
|
||||
return () => {
|
||||
if (raf) {
|
||||
cancelAnimationFrame(raf);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -2,60 +2,88 @@
|
||||
|
||||
You can check your organization's resource usage for the current billing cycle by navigating to your organization, under the **Usage** tab.
|
||||
|
||||
|
||||
## Reaching resource limits {% #reaching-resource-limits %}
|
||||
|
||||
Reaching your organization's resource limits will have the following effects until the current billing period ends.
|
||||
{% table %}
|
||||
* Component
|
||||
* Consequence
|
||||
---
|
||||
* **Bandwidth** {% rowspan=3 %}
|
||||
* More bandwidth will be purchased automatically until your organization reaches a budget cap. If the organization uses a Starter plan or a budget cap is reached, API access will be denied until your organization's plan is upgraded or your budget cap is increased.
|
||||
---
|
||||
* Importing projects via migrations disabled, but you can still export your projects.
|
||||
---
|
||||
* Platform creation disabled.
|
||||
---
|
||||
* **Users**
|
||||
* Creating new accounts and team invitations disabled.
|
||||
---
|
||||
* **Compute**
|
||||
* Function executions are disabled.
|
||||
---
|
||||
* **Realtime**
|
||||
* Realtime subscriptions disabled.
|
||||
---
|
||||
* **Storage**
|
||||
* File uploads are disabled. Persists across billing periods until the amount of storage used is below the plan limit.
|
||||
{% /table %}
|
||||
|
||||
## Switching to Starter plan and reaching limits {% #switching-to-starter-plan-reaching-resource-limits %}
|
||||
- Component
|
||||
- Consequence
|
||||
|
||||
When an orgnization switches from Pro or Scale plan to Starter plan, the organization's projects will be able to take advantage of the existing limits until the end of the current billing period.
|
||||
After the billing period ends, the Starter plan limits and consequences will apply.
|
||||
---
|
||||
|
||||
- **Bandwidth** {% rowspan=3 %}
|
||||
- More bandwidth will be purchased automatically until your organization reaches a budget cap. If the organization uses a Free plan or a budget cap is reached, API access will be denied until your organization's plan is upgraded or your budget cap is increased.
|
||||
|
||||
---
|
||||
|
||||
- Importing projects via migrations disabled, but you can still export your projects.
|
||||
|
||||
---
|
||||
|
||||
- Platform creation disabled.
|
||||
|
||||
---
|
||||
|
||||
- **Users**
|
||||
- Creating new accounts and team invitations disabled.
|
||||
|
||||
---
|
||||
|
||||
- **Compute**
|
||||
- Function executions are disabled.
|
||||
|
||||
---
|
||||
|
||||
- **Realtime**
|
||||
- Realtime subscriptions disabled.
|
||||
|
||||
---
|
||||
|
||||
- **Storage**
|
||||
- File uploads are disabled. Persists across billing periods until the amount of storage used is below the plan limit.
|
||||
{% /table %}
|
||||
|
||||
## Switching to Free plan and reaching limits {% #switching-to-free-plan-reaching-resource-limits %}
|
||||
|
||||
When an orgnization switches from Pro or Scale plan to Free plan, the organization's projects will be able to take advantage of the existing limits until the end of the current billing period.
|
||||
After the billing period ends, the Free plan limits and consequences will apply.
|
||||
|
||||
If an organisation has multiple members after the billing period ends, all admins besides the original creator of the organization will be removed.
|
||||
The following consequences should also apply at the project level if the Starter plan per-project resource limits have been exceeded.
|
||||
The following consequences should also apply at the project level if the Free plan per-project resource limits have been exceeded.
|
||||
|
||||
{% table %}
|
||||
* Component
|
||||
* Action
|
||||
|
||||
- Component
|
||||
- Action
|
||||
|
||||
---
|
||||
* **Platforms**
|
||||
* If more than 3 platforms have been created, disable them in order of date created (oldest ones first).
|
||||
|
||||
- **Platforms**
|
||||
- If more than 3 platforms have been created, disable them in order of date created (oldest ones first).
|
||||
|
||||
---
|
||||
* **Webhooks**
|
||||
* If more than 2 webhooks have been created, disable them in order of date created (oldest ones first).
|
||||
|
||||
- **Webhooks**
|
||||
- If more than 2 webhooks have been created, disable them in order of date created (oldest ones first).
|
||||
|
||||
---
|
||||
* **Teams**
|
||||
* If more than 100 teams have been created, disable them in order of date created (oldest ones first).
|
||||
|
||||
- **Teams**
|
||||
- If more than 100 teams have been created, disable them in order of date created (oldest ones first).
|
||||
|
||||
---
|
||||
* **Databases**
|
||||
* If more than 1 database has been created, disable them in order of date created (oldest ones first).
|
||||
|
||||
- **Databases**
|
||||
- If more than 1 database has been created, disable them in order of date created (oldest ones first).
|
||||
|
||||
---
|
||||
* **Buckets**
|
||||
* If more than 3 buckets have been created, disable them in order of date created (oldest ones first).
|
||||
|
||||
- **Buckets**
|
||||
- If more than 3 buckets have been created, disable them in order of date created (oldest ones first).
|
||||
|
||||
---
|
||||
* **Functions**
|
||||
* If more than 5 functions have been created, disable them in order of date created (oldest ones first).
|
||||
{% /table %}
|
||||
|
||||
- **Functions**
|
||||
- If more than 5 functions have been created, disable them in order of date created (oldest ones first).
|
||||
{% /table %}
|
||||
|
||||
@@ -659,6 +659,10 @@
|
||||
"link": "/docs/installation",
|
||||
"redirect": "/docs/advanced/self-hosting"
|
||||
},
|
||||
{
|
||||
"link": "/keyboard",
|
||||
"redirect": "/docs/tooling/appwriter"
|
||||
},
|
||||
{
|
||||
"link": "/careers",
|
||||
"redirect": "https://appwrite.careers"
|
||||
@@ -675,4 +679,4 @@
|
||||
"link": "/cli/install.sh",
|
||||
"redirect": "https://raw.githubusercontent.com/appwrite/sdk-for-cli/master/install.sh"
|
||||
}
|
||||
]
|
||||
]
|
||||
@@ -504,7 +504,7 @@
|
||||
style:left="0"
|
||||
>
|
||||
<div style:display="grid" style:place-items="center" style:height="100%">
|
||||
<img src="/images/bgs/diagonal-lines.png" alt="" width="512" />
|
||||
<img src="/images/bgs/diagonal-lines.png" alt="" width="512" loading="lazy" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="web-container u-position-relative">
|
||||
|
||||
@@ -58,8 +58,8 @@
|
||||
<enhanced:img src="./bg.png" alt="" />
|
||||
</div>
|
||||
|
||||
<Main>
|
||||
<TocRoot activeType="highest">
|
||||
<Main omitMainId>
|
||||
<TocRoot>
|
||||
<div class="web-container">
|
||||
<div class="web-grid-120-1fr-auto">
|
||||
<header class="web-grid-120-1fr-auto-header">
|
||||
@@ -124,11 +124,13 @@
|
||||
identity. Refrain from altering our logo and preferably use our
|
||||
logo on a neutral background.
|
||||
</p>
|
||||
<div class="u-flex u-flex-wrap u-gap-32 u-margin-block-start-12">
|
||||
<div
|
||||
class="u-flex u-flex-wrap web-u-flex-vertical-mobile u-gap-32 u-margin-block-start-12"
|
||||
>
|
||||
<div
|
||||
class="media-wrapper | theme-light |
|
||||
u-stretch web-u-flex-basis-300 u-flex u-main-center u-cross-center web-u-border-radius-8 web-u-padding-inline-64
|
||||
web-u-bg-color-neutral-100 web-u-block-size-320"
|
||||
web-u-bg-color-neutral-100 web-u-min-block-size-320"
|
||||
>
|
||||
<img
|
||||
src="/assets/logotype/white.svg"
|
||||
@@ -162,7 +164,7 @@
|
||||
<div
|
||||
class="media-wrapper | theme-dark |
|
||||
u-stretch web-u-flex-basis-300 u-flex u-main-center u-cross-center web-u-border-radius-8 web-u-padding-inline-64
|
||||
web-u-bg-color-neutral-800 web-u-block-size-320"
|
||||
web-u-bg-color-neutral-800 web-u-min-block-size-320"
|
||||
>
|
||||
<img
|
||||
src="/assets/logotype/black.svg"
|
||||
@@ -207,7 +209,7 @@
|
||||
</p>
|
||||
<div
|
||||
class="u-flex u-main-center u-cross-center u-margin-block-start-12 web-u-border-radius-8 u-padding-inline-16
|
||||
web-u-bg-color-neutral-800 web-u-block-size-320"
|
||||
web-u-bg-color-neutral-800 web-u-min-block-size-320"
|
||||
>
|
||||
<img
|
||||
src="/assets/logotype/co-brand.svg"
|
||||
@@ -233,11 +235,13 @@
|
||||
situations where space constraints make it challenging to
|
||||
showcase the complete logotype.
|
||||
</p>
|
||||
<div class="u-flex u-flex-wrap u-gap-32 u-margin-block-start-12">
|
||||
<div
|
||||
class="u-flex u-flex-wrap web-u-flex-vertical-mobile u-gap-32 u-margin-block-start-12"
|
||||
>
|
||||
<div
|
||||
class="media-wrapper | theme-light |
|
||||
u-stretch web-u-flex-basis-300 u-flex u-main-center u-cross-center web-u-border-radius-8 web-u-padding-inline-64
|
||||
web-u-bg-color-neutral-100 web-u-block-size-320"
|
||||
web-u-bg-color-neutral-100 web-u-min-block-size-320"
|
||||
>
|
||||
<img
|
||||
src="/assets/logomark/logo.svg"
|
||||
@@ -271,7 +275,7 @@
|
||||
<div
|
||||
class="media-wrapper | theme-dark |
|
||||
u-stretch web-u-flex-basis-300 u-flex u-main-center u-cross-center web-u-border-radius-8 web-u-padding-inline-64
|
||||
web-u-bg-color-neutral-800 web-u-block-size-320"
|
||||
web-u-bg-color-neutral-800 web-u-min-block-size-320"
|
||||
>
|
||||
<img
|
||||
src="/assets/logomark/logo.svg"
|
||||
@@ -316,7 +320,7 @@
|
||||
</p>
|
||||
<div
|
||||
class="u-flex u-main-center u-cross-center u-margin-block-start-12 web-u-border-radius-8 u-padding-inline-16
|
||||
web-u-bg-color-neutral-800 web-u-block-size-320"
|
||||
web-u-bg-color-neutral-800 web-u-min-block-size-320"
|
||||
>
|
||||
<img
|
||||
src="/assets/logomark/co-brand.svg"
|
||||
@@ -543,6 +547,37 @@
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="media-wrapper">
|
||||
<img
|
||||
class="web-u-border-radius-8 web-u-media-ratio-16-9 u-width-full-line"
|
||||
src="/assets/visuals/messaging.png"
|
||||
alt="Appwrite Messaging"
|
||||
/>
|
||||
<div class="buttons">
|
||||
<a
|
||||
class="web-button is-secondary"
|
||||
href="/assets/visuals/messaging.jpg"
|
||||
download
|
||||
>
|
||||
<span
|
||||
class="web-icon-download"
|
||||
aria-label="download"
|
||||
/>
|
||||
<span>JPG</span>
|
||||
</a>
|
||||
<a
|
||||
class="web-button is-secondary"
|
||||
href={'/assets/visuals/messaging.png'}
|
||||
download
|
||||
>
|
||||
<span
|
||||
class="web-icon-download"
|
||||
aria-label="download"
|
||||
/>
|
||||
<span>PNG</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
10
src/routes/blog/author/snezhanna/+page.markdoc
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
layout: author
|
||||
slug: snezhanna
|
||||
name: Snezhanna Markova
|
||||
role: Content and Socials
|
||||
bio: I handle all things content and socials @Appwrite
|
||||
avatar: /images/avatars/snezhanna.png
|
||||
linkedin: https://www.linkedin.com/in/snezhanna-markova/
|
||||
---
|
||||
|
||||
@@ -31,7 +31,7 @@ To create an OpenAI API key, we must first create an account on the [OpenAI pla
|
||||

|
||||
|
||||
> Note: To use the GPT-4 API, your account must be upgraded to the Usage tier 1. To learn more, visit their [Usage tiers documentation](https://platform.openai.com/docs/guides/rate-limits/usage-tiers?context=tier-one).
|
||||
>
|
||||
>
|
||||
|
||||
## GitHub
|
||||
|
||||
@@ -99,7 +99,7 @@ Visit the collection settings, enable **Document security,** and set the followi
|
||||
To build this app, we used SvelteKit, a framework to build web applications using JavaScript. There are some prerequisites, however, that must be completed before building out the features themselves.
|
||||
|
||||
> Note: The code snippets will focus only on the application logic. All CSS or styling-related information as well as any other miscellaneous features will be accessible in the final project repository at the end of the blog.
|
||||
>
|
||||
>
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@@ -172,8 +172,8 @@ const createUser = () => {
|
||||
store.set(null);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
function login() {
|
||||
@@ -322,7 +322,7 @@ We will be calling these functions for our main application page in the file `./
|
||||
|
||||
async function getTopFiveLanguages(username, token) {
|
||||
let languageUsage = {};
|
||||
|
||||
|
||||
const repositories = await github.getRepos(username, token);
|
||||
loadingMessage = `Checking 30 most-recently created repos...`;
|
||||
for (let repo of repositories) {
|
||||
@@ -349,12 +349,12 @@ We will be calling these functions for our main application page in the file `./
|
||||
async function initCrystalBall(userId) {
|
||||
// Check if GitHub data is already stored in Appwrite DB or not
|
||||
userData = await db.getUserData(userId);
|
||||
|
||||
|
||||
if(userData === false){
|
||||
// Get GitHub token from Appwrite session
|
||||
const session = await user.getSession();
|
||||
const githubToken = session.providerAccessToken;
|
||||
|
||||
|
||||
// Get GitHub user details
|
||||
const githubUser = await github.getUser(githubToken);
|
||||
const githubUsername = githubUser.login;
|
||||
@@ -396,7 +396,7 @@ We will be calling these functions for our main application page in the file `./
|
||||
<button id="ballClick" on:click={getDestiny}>Tap here and reveal your destiny!</button>
|
||||
{:else if destinyLoading === 'loading'}
|
||||
<img src={crystalball} alt="Crystal Ball">
|
||||
<button on:click={getDestiny}>Reading your future...</button>
|
||||
<button on:click={getDestiny}>Reading your future...</button>
|
||||
{:else if destinyLoading === 'complete'}
|
||||
<div class="destiny">
|
||||
<div class="destinyMessage">
|
||||
@@ -405,7 +405,7 @@ We will be calling these functions for our main application page in the file `./
|
||||
<p>{destiny}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="destinyButtons">
|
||||
<div class="destinyButtons">
|
||||
<button class="copyButton" on:click={getLink}>Get Link to Destiny</button>
|
||||
<button class="resetButton" on:click={resetDestiny}>Want a new destiny?</button>
|
||||
</div>
|
||||
@@ -434,7 +434,7 @@ export async function POST({ request }) {
|
||||
});
|
||||
|
||||
const userData = requestBody.userData;
|
||||
|
||||
|
||||
const prompt = `You have the following data on a developer from their GitHub account:\n\nGitHub username: ${userData.username}\nFollowers: ${userData.followers}\nFollowing: ${userData.following}\nTop 5 languages:\n${userData.languages.join(',')}\n\nBased on this data, create a humourous, realistic prediction to lightly roast the individual about what they'll be doing in 5 years from now. Do not explicitly include their GitHub data in the final message. Only use gender-neutral pronouns.`;
|
||||
const response = await openai.chat.completions.create({
|
||||
model: 'gpt-4',
|
||||
@@ -514,7 +514,7 @@ export const db = {**
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
|
||||
getDestiny: async(documentId) => {
|
||||
try{
|
||||
return await databases.getDocument(
|
||||
@@ -548,7 +548,7 @@ export const csr = false;
|
||||
|
||||
export async function load({ params }) {
|
||||
let destiny = await db.getDestiny(params.slug);
|
||||
|
||||
|
||||
return {
|
||||
destiny
|
||||
};
|
||||
@@ -568,7 +568,7 @@ We will render our page using the pre-fetched destiny here:
|
||||
|
||||
function discoverDestiny() {
|
||||
window.open(`https://${window.location.hostname}`, '_self');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="mainContainer">
|
||||
@@ -592,16 +592,16 @@ Lastly, we need to add a function in `./src/routes/app/+page.svelte` to store th
|
||||
async function getLink() {
|
||||
let destinyToSave = await db.addDestiny(userData.username, destiny);
|
||||
let url = `https://${window.location.hostname}/destiny/${destinyToSave.$id}`;
|
||||
window.open(url, '_blank');
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
```
|
||||
|
||||
# Next steps
|
||||
|
||||
And with that, our AI Crystal Ball project is ready! So far, since launching this application, over **375 users** have signed up and created their destinies.
|
||||
And with that, our AI Crystal Ball project is ready! So far, since launching this application, over **375 users** have signed up and created their destinies.
|
||||
|
||||
The web app is still live and can be tried at the following link: [aicrystalball.oberai.dev](https://aicrystalball.oberai.dev/)
|
||||
|
||||
You can find the application’s complete source code at this [GitHub Repo](https://github.com/adityaoberai/AI-Crystal-Ball/).
|
||||
|
||||
[Join us on Discord](http://appwrite.io/discord) to be the first to get updates and to be part of a vibrant community!
|
||||
[Join us on Discord](https://appwrite.io/discord) to be the first to get updates and to be part of a vibrant community!
|
||||
@@ -57,8 +57,8 @@ Use MSG91 for SMS notifications to mobile devices.
|
||||
{% cards_item href="/docs/products/messaging/telesign" title="Telesign" icon="icon-telesign" %}
|
||||
Use Telesign for SMS notifications to mobile devices.
|
||||
{% /cards_item %}
|
||||
{% cards_item href="/docs/products/messaging/textmagic" title="TextMagic" icon="web-icon-textmagic" %}
|
||||
Use TextMagic for SMS notifications to mobile devices.
|
||||
{% cards_item href="/docs/products/messaging/textmagic" title="Textmagic" icon="web-icon-textmagic" %}
|
||||
Use Textmagic for SMS notifications to mobile devices.
|
||||
{% /cards_item %}
|
||||
{% cards_item href="/docs/products/messaging/vonage" title="Vonage" icon="icon-vonage" %}
|
||||
Use Vonage for SMS notifications to mobile devices.
|
||||
@@ -93,13 +93,13 @@ You can send messages immediately or schedule them for future delivery. The Appw
|
||||
|
||||
To get started with messaging, you connect a provider, add topics and targets, and send your first message today for your project.
|
||||
|
||||
We will be adding more adopters over time and are open to contributions. Visit our [community page](https://appwrite.io/community) to learn more about contributing or add your issues directly to [GitHub](https://github.com/appwrite/appwrite/issues).
|
||||
We will be adding more adopters over time and are open to contributions. Visit our [community page](/community) to learn more about contributing or add your issues directly to [GitHub](https://github.com/appwrite/appwrite/issues).
|
||||
|
||||
Visit our documentation to learn more about Messaging, join us on Discord to be part of the discussion, view our blog and YouTube channel, or visit our GitHub repository to see our open-source code.
|
||||
|
||||
- [Docs](http://appwrite.io/docs/products/messaging)
|
||||
- [Docs](/docs/products/messaging)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
- [GitHub](https://github.com/appwrite/appwrite)
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ Let's examine the integrations, Function templates, and what's still to come.
|
||||
|
||||
## AI use cases and documentation
|
||||
|
||||
To make your life easier, we have added technical guides to our documentation covering [computer vision](https://appwrite.io/blog/post/state-of-computer-vision), [natural language processing](https://appwrite.io/blog/post/state-of-natural-language-processing), and [audio processing](https://appwrite.io/blog/post/state-of-audio-processing). These advanced tutorials explain how to use [AI and Appwrite](https://appwrite.io/docs/products/ai) in your projects.
|
||||
To make your life easier, we have added technical guides to our documentation covering [computer vision](https://appwrite.io/blog/post/state-of-computer-vision), [natural language processing](https://appwrite.io/blog/post/state-of-natural-language-processing), and [audio processing](https://appwrite.io/blog/post/state-of-audio-processing). These advanced tutorials explain how to use [AI and Appwrite](https://appwrite.io/docs/products/ai) in your projects.
|
||||
|
||||

|
||||
|
||||
@@ -40,7 +40,7 @@ We've also added support for many AI tools so you can integrate them into your p
|
||||
|
||||
## AI powered Function templates
|
||||
|
||||
Function templates are pre-built Appwrite [Function](https://appwrite.io/docs/products/functions) that can be integrated into your Appwrite project with just a few clicks. With templates, you can easily incorporate new features and integrations into your app without writing additional code or managing infrastructure.
|
||||
Function templates are pre-built Appwrite [Function](https://appwrite.io/docs/products/functions) that can be integrated into your Appwrite project with just a few clicks. With templates, you can easily incorporate new features and integrations into your app without writing additional code or managing infrastructure.
|
||||
|
||||
We have templates for your favorite AI tools, like OpenAI, LangChain, HuggingFace, and many more, covering many use cases, such as building an [intelligent chatbot](https://appwrite.io/blog/post/function-template-prompt-chatgpt) using OpenAI.
|
||||
|
||||
@@ -48,7 +48,7 @@ Find the full overview on your console under the `Templates` tab in `Fuctions`.
|
||||
|
||||

|
||||
|
||||
You can also find the full list of templates on [GitHub](https://github.com/appwrite/templates) and see what's to come.
|
||||
You can also find the full list of templates on [GitHub](https://github.com/appwrite/templates) and see what's to come.
|
||||
|
||||
## Building more AI features
|
||||
|
||||
@@ -56,7 +56,7 @@ Over the coming months, we will roll out more AI features to make building AI pr
|
||||
|
||||
### Vector database
|
||||
|
||||
Another advanced AI use case in the field of Natural Language Processing is the ability to use vector databases to store and process embeddings.
|
||||
Another advanced AI use case in the field of Natural Language Processing is the ability to use vector databases to store and process embeddings.
|
||||
|
||||
> Embeddings are numerical representations of words, sentences etc., and vector databases are optimized to store and perform similarity searches on the embeddings.
|
||||
|
||||
@@ -64,8 +64,8 @@ Adding a vector database will be another important milestone for making Appwrite
|
||||
|
||||
### AI marketplace
|
||||
|
||||
We will add an AI marketplace to encourage more open source collaboration on AI models and improve discoverability. The marketplace will allow you to build and share popular open-source and custom models. You can also host and sell your own custom models on the marketplace.
|
||||
We will add an AI marketplace to encourage more open source collaboration on AI models and improve discoverability. The marketplace will allow you to build and share popular open-source and custom models. You can also host and sell your own custom models on the marketplace.
|
||||
|
||||
## Building the future
|
||||
|
||||
The future of Appwrite is exciting, and we look forward to continuing to build exciting new features. Join us on [Discord](http://appwrite.io/discord) to participate in the discussion and have fun. For Appwrite and AI-powered projects, visit [builtwith.appwrite.io](https://apwr.dev/yAtAG8j).
|
||||
The future of Appwrite is exciting, and we look forward to continuing to build exciting new features. Join us on [Discord](https://appwrite.io/discord) to participate in the discussion and have fun. For Appwrite and AI-powered projects, visit [builtwith.appwrite.io](https://apwr.dev/yAtAG8j).
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
layout: post
|
||||
title: "Announcing: Appwrite Pro"
|
||||
description: We’re happy to introduce Appwrite Pro. After announcing our pricing plans for Appwrite Cloud in August, we have reached another milestone as we roll out billing and welcome our newest addition to Appwrite Cloud. A new product offering that allows you to build with more confidence.
|
||||
description: We’re happy to introduce Appwrite Pro. After announcing our pricing plans for Appwrite Cloud in August, we have reached another milestone as we roll out billing and welcome our newest addition to Appwrite Cloud. A new product offering that allows you to build with more confidence.
|
||||
date: 2023-12-20
|
||||
cover: /images/blog/announcing-appwrite-pro/header.png
|
||||
timeToRead: 5
|
||||
@@ -10,67 +10,65 @@ category: cloud
|
||||
featured: false
|
||||
---
|
||||
|
||||
After [announcing our pricing plans](https://appwrite.io/blog/post/announcing-pricing) for Appwrite Cloud in August, we have reached another milestone as we roll out billing and welcome our newest addition to Appwrite Cloud, Appwrite Pro. A new product offering that allows you to build with more confidence.
|
||||
After [announcing our pricing plans](https://appwrite.io/blog/post/announcing-pricing) for Appwrite Cloud in August, we have reached another milestone as we roll out billing and welcome our newest addition to Appwrite Cloud, Appwrite Pro. A new product offering that allows you to build with more confidence.
|
||||
|
||||
While Appwrite Cloud is still in beta, Appwrite Pro is a new chapter we write together. Pro will help us add more features and capabilities to Appwrite, making app development more accessible and enjoyable for developers like you.
|
||||
|
||||
# Appwrite Pro resources & support
|
||||
|
||||
Previously, all Appwrite Cloud developers used the Starter plan with unrestricted resources. This changes with Pro. Depending on your needs, you can choose between two different plans for your organization(s):
|
||||
Previously, all Appwrite Cloud developers used the Free plan with unrestricted resources. This changes with Pro. Depending on your needs, you can choose between two different plans for your organization(s):
|
||||
|
||||
- Starter: a free plan that provides an easy starting point for budding projects
|
||||
- Free: a free plan that provides an easy starting point for budding projects
|
||||
- Pro: a paid plan that offers more resources and premium support
|
||||
|
||||
As we explained in depth in our [Pricing announcement](https://appwrite.io/blog/post/announcing-pricing), our pricing plans are based on a set of guiding principles we created, which we call the “Value Framework.” It guided us through determining the resources in a Pro plan and a fair price. It focuses on delivering the maximum value for you without compromising on the affordability and accessibility of our products and services.
|
||||
|
||||
Pro gives you much more room and flexibility to build, scale, and maintain your apps compared to the Starter plan. Here is a snapshot of the differences in resources and support for Appwrite Starter and Appwrite Pro. You can find the complete overview on our [pricing page](https://appwrite.io/pricing#:~:text=Contact%20us-,Compare%20plans,-Discover%20our%20plans).
|
||||
Pro gives you much more room and flexibility to build, scale, and maintain your apps compared to the Free plan. Here is a snapshot of the differences in resources and support for Appwrite's Free and Pro plans. You can find the complete overview on our [pricing page](https://appwrite.io/pricing#:~:text=Contact%20us-,Compare%20plans,-Discover%20our%20plans).
|
||||
|
||||
{% table %}
|
||||
* Appwrite Starter
|
||||
* Appwrite Pro
|
||||
- Appwrite Free
|
||||
- Appwrite Pro
|
||||
---
|
||||
* **Free**
|
||||
* **$15 per member per month**
|
||||
- **Free**
|
||||
- **$15 per member per month**
|
||||
---
|
||||
* Unlimited projects (never paused)
|
||||
* Unlimited projects (never paused)
|
||||
- Unlimited projects (never paused)
|
||||
- Unlimited projects (never paused)
|
||||
---
|
||||
* 10GB bandwidth
|
||||
* 300GB bandwidth
|
||||
- 10GB bandwidth
|
||||
- 300GB bandwidth
|
||||
---
|
||||
* 2GB storage
|
||||
* 150GB storage
|
||||
- 2GB storage
|
||||
- 150GB storage
|
||||
---
|
||||
* 750K executions
|
||||
* 3.5M executions
|
||||
- 750K executions
|
||||
- 3.5M executions
|
||||
---
|
||||
* 75K monthly active users
|
||||
* 200K monthly active users
|
||||
- 75K monthly active users
|
||||
- 200K monthly active users
|
||||
---
|
||||
* Community support
|
||||
* Email support
|
||||
- Community support
|
||||
- Email support
|
||||
---
|
||||
* Non-removable Appwrite branding
|
||||
* Removable Appwrite branding
|
||||
- Non-removable Appwrite branding
|
||||
- Removable Appwrite branding
|
||||
---
|
||||
* No add-on resources
|
||||
* Add-on resources
|
||||
---
|
||||
* 1 Database, 3 Buckets, 5 Functions per project
|
||||
* Unlimited Databases, Buckets, and Functions
|
||||
- No add-on resources
|
||||
- Add-on resources
|
||||
---
|
||||
- 1 Database, 3 Buckets, 5 Functions per project
|
||||
- Unlimited Databases, Buckets, and Functions
|
||||
{% /table %}
|
||||
|
||||
|
||||
## Authentication, Bandwidth & Monthly active users
|
||||
|
||||
With 300GB bandwidth and 200K monthly active users in the Pro plan, we ensure you can scale your user base and provide great performance for your users without facing large bills. Allowing this room for your growth at a low cost fits our philosophy that we grow together.
|
||||
|
||||
## Databases, Buckets & Storage
|
||||
|
||||
Another essential addition to your projects is having an unlimited number of databases, allowing you to tailor and optimize your data management. You can manage different data types and patterns, separate concerns, have stricter data governance and security and optimize performance. All are very necessary for more complex and demanding software applications.
|
||||
Another essential addition to your projects is having an unlimited number of databases, allowing you to tailor and optimize your data management. You can manage different data types and patterns, separate concerns, have stricter data governance and security and optimize performance. All are very necessary for more complex and demanding software applications.
|
||||
|
||||
Again, you’re allowed unlimited buckets. This provides several benefits, including improved organization, scalability, modularity, data redundancy, storage cost management, and data governance. With a starting point of 150GB storage, you can grow your projects instantly without reaching high costs, allowing you to grow in production at a low cost.
|
||||
Again, you’re allowed unlimited buckets. This provides several benefits, including improved organization, scalability, modularity, data redundancy, storage cost management, and data governance. With a starting point of 150GB storage, you can grow your projects instantly without reaching high costs, allowing you to grow in production at a low cost.
|
||||
|
||||
## Functions & Executions
|
||||
|
||||
@@ -78,7 +76,7 @@ Having unlimited functions is a must-have for many, as it is the holy grail for
|
||||
|
||||
## Customization
|
||||
|
||||
For a production product, you need more control of your brand, as well as the flexibility to add to your plan as it evolves. Within the Pro plan, it is possible to remove Appwrite branding from emails, have custom SMTP, and get resource add-ons to fit your needs.
|
||||
For a production product, you need more control of your brand, as well as the flexibility to add to your plan as it evolves. Within the Pro plan, it is possible to remove Appwrite branding from emails, have custom SMTP, and get resource add-ons to fit your needs.
|
||||
|
||||
## Premium support
|
||||
|
||||
@@ -98,7 +96,7 @@ Beta developers are fundamental to the success of Appwrite Cloud today, and we a
|
||||
|
||||
## Existing organizations and projects
|
||||
|
||||
Early adopters of Appwrite Cloud may already have a large number of organizations and projects. With the release of Appwrite Pro, each Appwrite Cloud account will have access to only one free Starter organization. Additional projects will be paused. You can find an overview of your project’s resources on the Appwrite Console. To help you make a smooth transition, you can take one of the following options.
|
||||
Early adopters of Appwrite Cloud may already have a large number of organizations and projects. With the release of Appwrite Pro, each Appwrite Cloud account will have access to only one free organization. Additional projects will be paused. You can find an overview of your project’s resources on the Appwrite Console. To help you make a smooth transition, you can take one of the following options.
|
||||
|
||||
- Upgrade additional organizations to the Pro plan using your early adopters’ credit.
|
||||
- Move your projects using the **Transfer project** feature in your project’s settings.
|
||||
@@ -110,7 +108,7 @@ We appreciate the support and feedback from early Cloud adopters. These options
|
||||
|
||||
Open-source software forms the foundation of modern software technologies. As lovers and builders of open-source software, we understand and appreciate the difficulty of building in the open. We’re fortunate to have the opportunity to build open-source software sustainably, and we can’t wait to give back.
|
||||
|
||||
Like our previous initiatives, such as the OSS Fund, Appwrite Cloud will also support open-source developers. OSS maintainers can use Appwrite to build and maintain their projects on the Appwrite Pro plan for free. Please reach out on our [contact page](https://apwr.dev/OSSplan) to enquire about this plan. As always, Appwrite also remains open-sourced and free to [self-host](https://appwrite.io/docs/advanced/self-hosting).
|
||||
Like our previous initiatives, such as the OSS Fund, Appwrite Cloud will also support open-source developers. OSS maintainers can use Appwrite to build and maintain their projects on the Appwrite Pro plan for free. Please reach out on our [contact page](https://apwr.dev/OSSplan) to enquire about this plan. As always, Appwrite also remains open-sourced and free to [self-host](https://appwrite.io/docs/advanced/self-hosting).
|
||||
|
||||
Appwrite Pro is just the start. We will continue developing our product offering to match your growing needs and capabilities and are excited to see your projects succeed with Appwrite Cloud. While you benefit from everything Appwrite Pro has to offer, you also become advocates in our mission to make software development accessible and enjoyable for all.
|
||||
|
||||
@@ -126,4 +124,4 @@ In case you need help upgrading, transferring your projects, or have billing and
|
||||
|
||||
- [FAQ on pricing page](https://apwr.dev/pricingFAQ)
|
||||
- [Project migration](https://appwrite.io/docs/advanced/migrations/cloud)
|
||||
- [Discord support](http://appwrite.io/discord)
|
||||
- [Discord support](https://appwrite.io/discord)
|
||||
|
||||
@@ -53,8 +53,8 @@ Join a growing community of developers and founders who use Appwrite to build th
|
||||
|
||||
To join the program, you must be VC-backed or have a $500k ARR, and your company has to be established within the last decade.
|
||||
|
||||
Visit our dedicated [startups program page](https://appwrite.io/startups) to learn more and apply. If you have questions, please [reach out to us](https://appwrite.io/contact-us).
|
||||
Visit our dedicated [startups program page](/startups) to learn more and apply. If you have questions, please [reach out to us](/contact-us).
|
||||
|
||||
## Resources
|
||||
|
||||
Learn more about Appwrite in our [documentation](https://appwrite.io/docs). Check out our [blog](https://appwrite.io/blog) for the latest Appwrite news and content, and engage with the Appwrite team and community on [Discord](https://appwrite.io/discord).
|
||||
Learn more about Appwrite in our [documentation](/docs). Check out our [blog](/blog) for the latest Appwrite news and content, and engage with the Appwrite team and community on [Discord](https://appwrite.io/discord).
|
||||
|
||||
@@ -15,7 +15,7 @@ We’re excited to have updated versions so you can build with your preferred te
|
||||
|
||||
# Bun, blazing fast and built for web
|
||||
|
||||
[Bun](https://bun.sh/) is an amazingly fast runtime, dependency manager, test runner, and web server for JavaScript with unique features that make it a perfect fit for Appwrite Functions. Bun is fast, like really fast. The runtime performance, dependency manager, and test runners are noticeably faster than its many Node.js counterparts. This is a topic well discussed in [benchmarks](https://medium.com/deno-the-complete-reference/is-bun-really-much-faster-than-node-js-e5b15942a8e8).
|
||||
[Bun](https://bun.sh/) is an amazingly fast runtime, dependency manager, test runner, and web server for JavaScript with unique features that make it a perfect fit for Appwrite Functions. Bun is fast, like really fast. The runtime performance, dependency manager, and test runners are noticeably faster than its many Node.js counterparts. This is a topic well discussed in [benchmarks](https://medium.com/deno-the-complete-reference/is-bun-really-much-faster-than-node-js-e5b15942a8e8).
|
||||
|
||||
Bun also boasts a robust standard library. It enables TypeScript and JSX out of the box without a build step, implements standard Web APIs like `fetch()`, and comes with a built-in test runner. All this reduces build times and dependencies needed. Our Bun 1.0.29 runtime brings improved compatibility with the NPM ecosystem and countless bug fixes.
|
||||
|
||||
@@ -41,7 +41,7 @@ Ruby 3.3 brings some noteworthy upgrades to the table. First off, there’s YJIT
|
||||
|
||||
# Updated runtimes for Appwrite
|
||||
|
||||
For better dependency compatibility and to reduce vulnerabilities, we've also updated many other runtimes with new versions:
|
||||
For better dependency compatibility and to reduce vulnerabilities, we've also updated many other runtimes with new versions:
|
||||
|
||||
- Node 21
|
||||
- Deno 1.40
|
||||
@@ -59,8 +59,8 @@ Try the new runtimes on Appwrite with zero lines of new code using function temp
|
||||
|
||||
Visit our documentation to learn more about the runtimes, join us on Discord to be part of the discussion, view our blog and YouTube channel, or visit our GitHub repository to see our open-source code.
|
||||
|
||||
- [Docs](https://appwrite.io/docs/products/functions/runtimes)
|
||||
- [Docs](/docs/products/functions/runtimes)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
- [GitHub](https://github.com/appwrite/appwrite)
|
||||
|
||||
@@ -36,16 +36,19 @@ The above framework supports our goal to make Appwrite Cloud affordable and acce
|
||||
|
||||

|
||||
|
||||
**Starter Plan**
|
||||
- A free tier for every developer working on a side project or SaaS product that can thrive on our starter plan limits.
|
||||
**Free plan**
|
||||
|
||||
- A free tier for every developer working on a side project or SaaS product that can thrive on our Free plan limits.
|
||||
- Free.
|
||||
|
||||
**Pro Plan**
|
||||
|
||||
- A plan that supports your ambitions to scale your production project and allows you to grow. With flexible budget control tools to ensure you never get a surprise bill.
|
||||
- $15, per month, per member.
|
||||
|
||||
**Scale plan**
|
||||
- A plan that offers more support as you continue to scale your commercial product and team. With higher limits and more support from our team to ensure we support the demand of scaling teams.
|
||||
|
||||
- A plan that offers more support as you continue to scale your commercial product and team. With higher limits and more support from our team to ensure we support the demand of scaling teams.
|
||||
- $685, per month, per organization.
|
||||
|
||||
# Business model: Pay per organization member
|
||||
@@ -59,6 +62,7 @@ Our business model is designed to support developers with a lot of freedom to bu
|
||||
One thing we cannot dismiss is our OSS program. We strongly believe in helping other Open Source (OSS) maintainers. We know very well where we came from and Appwrite has been built with and by the open-source community. Therefore we have a free program to support the OSS community and show our appreciation. Interested developers can apply on our website once pricing is available.
|
||||
|
||||
# Next steps
|
||||
|
||||
This is a big step forward for Appwrite and the community and we are excited to see the response to our plans. The coming weeks we will work hard on making our pricing available, but until then developers can continue to build on Appwrite free of charge.
|
||||
|
||||
- [Review the pricing comparison](/pricing)
|
||||
|
||||
@@ -33,7 +33,7 @@ Currently, Appwrite offers three methods for implementing the second factor:
|
||||
|
||||
# Implementing 2FA in your apps
|
||||
|
||||
One great aspect of Appwrite 2FA is that it can be used in conjunction with any existing authentication method you have implemented using Appwrite Auth. You can implement 2FA in your application via the following several steps.
|
||||
One great aspect of Appwrite 2FA is that it can be used in conjunction with any existing authentication method you have implemented using Appwrite Auth. You can implement 2FA in your application via the following several steps.
|
||||
|
||||
## Step 1: Enable 2FA on an account
|
||||
|
||||
@@ -86,7 +86,7 @@ try {
|
||||
|
||||
## Step 3: Check enabled factors
|
||||
|
||||
To confirm which providers are enabled for an account, you can call `account.listProviders()`.
|
||||
To confirm which providers are enabled for an account, you can call `account.listProviders()`.
|
||||
|
||||
```js
|
||||
const factors = await account.listFactors();
|
||||
@@ -136,9 +136,9 @@ While Appwrite currently allows two factors of authentication, we intend to make
|
||||
|
||||
Visit our documentation to learn more about Appwrite, join us on Discord to be part of the discussion, view our blog and YouTube channel, or visit our GitHub repository to see our open-source code.
|
||||
|
||||
- [Docs](https://appwrite.io/docs/products/auth/mfa)
|
||||
- [Docs](/docs/products/auth/mfa)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
- [GitHub](https://github.com/appwrite/appwrite)
|
||||
|
||||
|
||||
@@ -10,13 +10,13 @@ category: product
|
||||
featured: false
|
||||
---
|
||||
|
||||
After announcing many new products and features during [Init](https://appwrite.io/init) as part of the 1.5 release, we saw great excitement within the community to get started with the newly presented Appwrite 1.5. Although already available on self-hosted, the new Appwrite products and features were yet to be released to Cloud. Today, we are excited to say the wait is finally over as we announce the release of Appwrite 1.5 to the Cloud.
|
||||
After announcing many new products and features during [Init](/init) as part of the 1.5 release, we saw great excitement within the community to get started with the newly presented Appwrite 1.5. Although already available on self-hosted, the new Appwrite products and features were yet to be released to Cloud. Today, we are excited to say the wait is finally over as we announce the release of Appwrite 1.5 to the Cloud.
|
||||
|
||||
To refresh your mind, here is an overview of all products and features released to Cloud and how you can get started.
|
||||
|
||||
# Messaging
|
||||
|
||||
With just a few lines of backend code, you can now set up a full-functioning messaging service for your application that covers three significant communication channels under one unified API using Cloud. You can send SMS, email, and push notifications through popular third-party providers like [Twilio](https://appwrite.io/blog/post/simplify-messaging-twilio), APNS, Firebase Cloud Messaging, Vonage, Sendgrid, and Mailgun.
|
||||
With just a few lines of backend code, you can now set up a full-functioning messaging service for your application that covers three significant communication channels under one unified API using Cloud. You can send SMS, email, and push notifications through popular third-party providers like [Twilio](/blog/post/simplify-messaging-twilio), APNS, Firebase Cloud Messaging, Vonage, Sendgrid, and Mailgun.
|
||||
|
||||
## Highlights
|
||||
|
||||
@@ -27,7 +27,7 @@ With just a few lines of backend code, you can now set up a full-functioning mes
|
||||
|
||||
## Emails
|
||||
|
||||
With Appwrite Messaging you can send custom email messages to your app's users. Appwrite supports [Mailgun](https://appwrite.io/docs/products/messaging/mailgun/) and [Sendgrid](https://appwrite.io/docs/products/messaging/sendgrid/) as SMTP providers. You must configure one of them as a provider before you can get started.
|
||||
With Appwrite Messaging you can send custom email messages to your app's users. Appwrite supports [Mailgun](/docs/products/messaging/mailgun/) and [Sendgrid](/docs/products/messaging/sendgrid/) as SMTP providers. You must configure one of them as a provider before you can get started.
|
||||
|
||||
Once you have finished the setup, you can send emails using a Server SDK. To send an email immediately, you can call the `createEmail` endpoint with the schedule left empty.
|
||||
|
||||
@@ -54,11 +54,11 @@ let message = try await messaging.createEmail(
|
||||
)
|
||||
```
|
||||
|
||||
Learn how to get started with [email in our documentation](https://appwrite.io/docs/products/messaging/send-email-messages).
|
||||
Learn how to get started with [email in our documentation](/docs/products/messaging/send-email-messages).
|
||||
|
||||
## SMS
|
||||
|
||||
To send SMS messages to you users you will need to add SMPT provider. Appwrite supports [Twilio](https://appwrite.io/docs/products/messaging/twilio/), [MSG91](https://appwrite.io/docs/products/messaging/msg91/), [Telesign](https://appwrite.io/docs/products/messaging/telesign/), [TextMagic](https://appwrite.io/docs/products/messaging/textmagic/), and [Vonage](https://appwrite.io/docs/products/messaging/vonage/).
|
||||
To send SMS messages to you users you will need to add SMPT provider. Appwrite supports [Twilio](/docs/products/messaging/twilio/), [MSG91](/docs/products/messaging/msg91/), [Telesign](/docs/products/messaging/telesign/), [Textmagic](/docs/products/messaging/textmagic/), and [Vonage](/docs/products/messaging/vonage/).
|
||||
|
||||
You can send SMS messages using a Server SDK. To send SMS messages immediately, you can call the `createSMS` endpoint without passing either the draft or `scheduled` parameters.
|
||||
|
||||
@@ -79,7 +79,7 @@ let message = try await messaging.createSMS(
|
||||
)
|
||||
```
|
||||
|
||||
Learn how to get started with [SMS in our documentation](https://appwrite.io/docs/products/messaging/send-sms-messages).
|
||||
Learn how to get started with [SMS in our documentation](/docs/products/messaging/send-sms-messages).
|
||||
|
||||
## Push notifications
|
||||
|
||||
@@ -87,7 +87,7 @@ If you're building a mobile app, note that push notifications must be sent throu
|
||||
|
||||
You must configure these services before you can send your first push notification.
|
||||
|
||||
To send with APNS, you must first register for remote notifications in your app delegate's application using the (_:didFinishLaunchingWithOptions:) method.
|
||||
To send with APNS, you must first register for remote notifications in your app delegate's application using the (_:didFinishLaunchingWithOptions:) method.
|
||||
|
||||
```swift
|
||||
func application(
|
||||
@@ -124,11 +124,11 @@ Configure FCM for push notification to Android and Apple devices.
|
||||
{% /cards_item %}
|
||||
{% /cards %}
|
||||
|
||||
Read the [Messaging announcement](https://appwrite.io/blog/post/announcing-appwrite-messaging) for a full overview of capabilities.
|
||||
Read the [Messaging announcement](/blog/post/announcing-appwrite-messaging) for a full overview of capabilities.
|
||||
|
||||
# Improved support for Server-Side Rendering (SSR)
|
||||
|
||||
Appwrite Cloud 1.5 brings enhanced support for SSR authentication patterns, optimizing the platform for use with frameworks like [NextJS](https://appwrite.io/docs/tutorials/nextjs-ssr-auth/step-1), [SvelteKit](https://appwrite.io/docs/tutorials/sveltekit-ssr-auth/step-1), and [Nuxt](https://appwrite.io/docs/tutorials/nuxt-ssr-auth/step-1). This update introduces official methods for generating and accessing sessions server-side, allowing for seamless session cookies management and authorized requests, thus bridging the gap between client and server-side rendering.
|
||||
Appwrite Cloud 1.5 brings enhanced support for SSR authentication patterns, optimizing the platform for use with frameworks like [NextJS](/docs/tutorials/nextjs-ssr-auth/step-1), [SvelteKit](/docs/tutorials/sveltekit-ssr-auth/step-1), and [Nuxt](/docs/tutorials/nuxt-ssr-auth/step-1). This update introduces official methods for generating and accessing sessions server-side, allowing for seamless session cookies management and authorized requests, thus bridging the gap between client and server-side rendering.
|
||||
|
||||
## Highlights
|
||||
|
||||
@@ -150,7 +150,7 @@ client.setSession(session.secret)
|
||||
const currentUser = await account.get()
|
||||
```
|
||||
|
||||
Read the [SSR announcement](https://appwrite.io/blog/post/introducing-support-for-server-side-rendering) to get a full overview of capabilities or visit our documentation to get started.
|
||||
Read the [SSR announcement](/blog/post/introducing-support-for-server-side-rendering) to get a full overview of capabilities or visit our documentation to get started.
|
||||
|
||||
# Two-Factor Authentication (2FA)
|
||||
|
||||
@@ -184,7 +184,7 @@ const account = new Account(client);
|
||||
const mfa = await account.updateMFA(true); // Enables 2FA
|
||||
```
|
||||
|
||||
Read the [2FA announcement](https://appwrite.io/blog/post/announcing-two-factor-authentication) for a full overview of capabilities, or visit our [documentation](https://appwrite.io/docs/products/auth/mfa) to get started.
|
||||
Read the [2FA announcement](/blog/post/announcing-two-factor-authentication) for a full overview of capabilities, or visit our [documentation](/docs/products/auth/mfa) to get started.
|
||||
|
||||
# New Database operators
|
||||
|
||||
@@ -225,7 +225,7 @@ db.listDocuments(
|
||||
)
|
||||
```
|
||||
|
||||
Read the [Database operators announcement](https://appwrite.io/blog/post/introducing-new-database-operators) for a full overview of capabilities, or visit our [documentation](https://appwrite.io/docs/products/databases/queries) to get started.
|
||||
Read the [Database operators announcement](/blog/post/introducing-new-database-operators) for a full overview of capabilities, or visit our [documentation](/docs/products/databases/queries) to get started.
|
||||
|
||||
# Enum SDK Support
|
||||
|
||||
@@ -251,17 +251,17 @@ const account = new Account(client);
|
||||
account.createOAuth2Session(OAuthProvider.Apple);
|
||||
```
|
||||
|
||||
Read the [Enum SDK support](https://appwrite.io/blog/post/introducing-enum-sdk-support) announcements for a full overview of capabilities, and visit our [Enum](https://appwrite.io/docs/sdks#enums) documentation to get started.
|
||||
Read the [Enum SDK support](/blog/post/introducing-enum-sdk-support) announcements for a full overview of capabilities, and visit our [Enum](/docs/sdks#enums) documentation to get started.
|
||||
|
||||
# Custom token login
|
||||
|
||||
One feature that was not announced during Init but was recently released is custom token login. Tokens are short-lived secrets created by an [Appwrite Server SDK](https://appwrite.io/docs/sdks#server) that can be exchanged for a session by a [Client SDK](https://appwrite.io/docs/sdks#client) to log in users. You may already be familiar with tokens if you checked out [Magic URL login](https://appwrite.io/docs/products/auth/magic-url), [Email OTP login](https://appwrite.io/docs/products/auth/email-otp), or [Phone (SMS) login](https://appwrite.io/docs/products/auth/phone-sms).
|
||||
One feature that was not announced during Init but was recently released is custom token login. Tokens are short-lived secrets created by an [Appwrite Server SDK](/docs/sdks#server) that can be exchanged for a session by a [Client SDK](/docs/sdks#client) to log in users. You may already be familiar with tokens if you checked out [Magic URL login](/docs/products/auth/magic-url), [Email OTP login](/docs/products/auth/email-otp), or [Phone (SMS) login](/docs/products/auth/phone-sms).
|
||||
|
||||
Custom token allows you to use a [Server SDK](https://appwrite.io/docs/sdks#server) to generate tokens for your own auth implementations. This allows you to code your own authentication methods using Appwrite Functions or your own backend. You could implement username and password sign-in, captcha-protected authentication, phone call auth, and much more. Custom tokens also allow you to integrate Appwrite with external authentication providers such as Auth0, TypingDNA, or any provider trusted by your users.
|
||||
Custom token allows you to use a [Server SDK](/docs/sdks#server) to generate tokens for your own auth implementations. This allows you to code your own authentication methods using Appwrite Functions or your own backend. You could implement username and password sign-in, captcha-protected authentication, phone call auth, and much more. Custom tokens also allow you to integrate Appwrite with external authentication providers such as Auth0, TypingDNA, or any provider trusted by your users.
|
||||
|
||||
## Creating your custom token
|
||||
|
||||
Once you have prepared your own login flow in an Appwrite Function or a server integration, you can use the [Create token](https://appwrite.io/docs/references/1.5.x/server-nodejs/users#createToken) endpoint of the [Users API](https://appwrite.io/docs/products/auth/users) to generate a token.
|
||||
Once you have prepared your own login flow in an Appwrite Function or a server integration, you can use the [Create token](/docs/references/1.5.x/server-nodejs/users#createToken) endpoint of the [Users API](/docs/products/auth/users) to generate a token.
|
||||
|
||||
```swift
|
||||
// Server-side code
|
||||
@@ -282,7 +282,7 @@ let session = try await account.createSession(
|
||||
secret: "[SECRET]");
|
||||
```
|
||||
|
||||
Visit our [documentation](https://appwrite.io/docs/products/auth/custom-token) to learn more.
|
||||
Visit our [documentation](/docs/products/auth/custom-token) to learn more.
|
||||
|
||||
# Get started with Appwrite 1.5 on Cloud
|
||||
|
||||
@@ -290,6 +290,6 @@ This release brings you more flexibility, security, and safety when building wit
|
||||
|
||||
To get started, visit our documentation, YouTube channel, or get support on Discord.
|
||||
|
||||
- [Documentation](https://appwrite.io/docs)
|
||||
- [Documentation](/docs)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
|
||||
@@ -15,7 +15,7 @@ This article will give you a rundown of Appwrite and Supabase to understand the
|
||||
|
||||
# Appwrite
|
||||
|
||||
In 2019, [Appwrite](https://appwrite.io/) started as an open-source project to make software development more accessible and enjoyable. It is a Backend as a Service platform with a vibrant developer community. You can self-host Appwrite on your server or utilize [Appwrite Cloud](https://cloud.appwrite.io/). Appwrite provides a wide range of features, including user authentication, databases, storage, real-time features, and functions. It is known for its flexibility, security, and extensibility, enabling you to implement custom backend logic and build applications tailored to your needs. You can view Appwrite’s source code on [GitHub](https://github.com/appwrite/appwrite).
|
||||
In 2019, [Appwrite](/) started as an open-source project to make software development more accessible and enjoyable. It is a Backend as a Service platform with a vibrant developer community. You can self-host Appwrite on your server or utilize [Appwrite Cloud](https://cloud.appwrite.io/). Appwrite provides a wide range of features, including user authentication, databases, storage, real-time features, and functions. It is known for its flexibility, security, and extensibility, enabling you to implement custom backend logic and build applications tailored to your needs. You can view Appwrite’s source code on [GitHub](https://github.com/appwrite/appwrite).
|
||||
|
||||
# Supabase
|
||||
|
||||
@@ -37,7 +37,7 @@ Authentication is the process of verifying a user's identity to ensure that only
|
||||
|
||||
*Differences:*
|
||||
|
||||
- Appwrite's authentication system allows developers to integrate with any existing external authentication systems through [custom token login](https://appwrite.io/docs/products/auth/custom-token).
|
||||
- Appwrite's authentication system allows developers to integrate with any existing external authentication systems through [custom token login](/docs/products/auth/custom-token).
|
||||
- Appwrite provides two user grouping and categorization features: teams and labels, for simpler permissions management.
|
||||
- Supabase offers integration with SAML for enterprise SSO.
|
||||
|
||||
@@ -85,7 +85,7 @@ Functions are "self-contained" modules of code that accomplish a specific task.
|
||||
|
||||
*Differences:*
|
||||
|
||||
- Appwrite supports [functions runtimes across over 10 programming languages](https://appwrite.io/docs/products/functions/runtimes), including JavaScript, Python, PHP, and Dart, whereas Supabase officially supports only one programming language, TypeScript.
|
||||
- Appwrite supports [functions runtimes across over 10 programming languages](/docs/products/functions/runtimes), including JavaScript, Python, PHP, and Dart, whereas Supabase officially supports only one programming language, TypeScript.
|
||||
- Appwrite’s functions runtimes have been developed in-house, enabling a more curated developer experience and the ability to develop runtimes more quickly, whereas Supabase uses a 3rd party offering, limiting the pace of development and control over experience.
|
||||
- Appwrite offers a marketplace of function templates that are ready to deploy with a few button clicks, which Supabase does not offer.
|
||||
|
||||
@@ -127,7 +127,7 @@ Self-hosting support essentially means a developer can deploy the application on
|
||||
|
||||
*Differences:*
|
||||
|
||||
- Appwrite offers a [single installation command](https://appwrite.io/docs/advanced/self-hosting#install-with-docker) with a pre-built configuration to simplify the self-hosting process, making it more straightforward and cohesive. Supabase, on the other hand, expects the developer to manually configure each component during the setup process.
|
||||
- Appwrite offers a [single installation command](/docs/advanced/self-hosting#install-with-docker) with a pre-built configuration to simplify the self-hosting process, making it more straightforward and cohesive. Supabase, on the other hand, expects the developer to manually configure each component during the setup process.
|
||||
- Appwrite offers one-click setups for DigitalOcean, Gitpod, and Akamai Compute. Supabase offers the same for DigitalOcean and AWS.
|
||||
- Supabase features community-maintained helm charts to self-host using Kubernetes.
|
||||
|
||||
@@ -157,7 +157,7 @@ Here’s a table that compares both Appwrite and Supabase:
|
||||
| Database | Relational (MariaDB) | Relational (PostgreSQL) |
|
||||
| Serverless functions runtimes | 10+ languages supported | Only 1 language officially supported |
|
||||
| Self-hosting / Cloud | Self-hosting and Cloud available | Self-hosting and Cloud available |
|
||||
| Supported programming languages | Supports https://appwrite.io/docs/sdks in 10 languages JavaScript, Python, PHP, Kotlin, Dart | Supports SDKs in 6 languages |
|
||||
| Supported programming languages | Supports [SDKs](/docs/sdks) in 10 languages JavaScript, Python, PHP, Kotlin, Dart | Supports SDKs in 6 languages |
|
||||
| Pausing of projects | Free projects are not paused ever | Free projects are paused after 1 week of inactivity |
|
||||
| Functions marketplace | Has a marketplace featuring a variety of function templates and integrations such as Discord bots, payments with Stripe, ChatGPT API, etc. | No functions marketplace |
|
||||
| Permissions | A simple-to-use permissions system that is consistent across all Appwrite products | Complex permissions system that needs knowledge of SQL to get started |
|
||||
@@ -174,8 +174,8 @@ Here's a price comparison between Appwrite and Supabase to help you choose the o
|
||||
|
||||
If you want to learn more about Appwrite, you can find more resources below.
|
||||
|
||||
- [Appwrite documentation](https://appwrite.io/docs) - Visit Appwrite’s docs to learn how to get started and more about Appwrite’s functionality.
|
||||
- [Appwrite Migration API](https://appwrite.io/docs/advanced/migrations/supabase) - Find out how to transfer your applications from Supabase to Appwrite in just a few steps.
|
||||
- [Appwrite documentation](/docs) - Visit Appwrite’s docs to learn how to get started and more about Appwrite’s functionality.
|
||||
- [Appwrite Migration API](/docs/advanced/migrations/supabase) - Find out how to transfer your applications from Supabase to Appwrite in just a few steps.
|
||||
- [Appwrite GitHub repo](https://github.com/appwrite/appwrite/stargazers) - Explore Appwrite’s code and architecture and see how you can contribute to Appwrite.
|
||||
- [Appwrite Discord](https://appwrite.io/discord) - Join Appwrite’s Discord server and be part of a vibrant community.
|
||||
- [Appwrite YouTube](https://www.youtube.com/@Appwrite) - Visit Appwrite YouTube for hands-on tutorials to help you learn.
|
||||
- [Appwrite YouTube](https://www.youtube.com/@Appwrite) - Visit Appwrite YouTube for hands-on tutorials to help you learn.
|
||||
|
||||
127
src/routes/blog/post/appwrite-decoded-dylan/+page.markdoc
Normal file
@@ -0,0 +1,127 @@
|
||||
---
|
||||
layout: post
|
||||
title: "Appwrite Decoded: Dylan Graham"
|
||||
description: In this blog, we hear from our finance and operations lead, Dylan Graham.
|
||||
cover: /images/blog/appwrite-decoded-dylan/appwrite-decoded-dylan-blog-cover.png
|
||||
timeToRead: 8
|
||||
date: 2024-06-04
|
||||
author: laura-du-ry
|
||||
category: culture
|
||||
---
|
||||
The team behind Appwrite is spread across the globe and works together daily in different time zones. We’re proud of the remote and open-source culture the team has built so far. In Appwrite Decoded, we introduce the people behind the code and celebrate them.
|
||||
|
||||
In this blog, we will take you through our operations and finance lead’s career journey, Dylan Graham, whose experiences are as diverse as the Appwrite team.
|
||||
|
||||
# Landing the perfect role
|
||||
|
||||
After a gap year in post-secondary school, Dylan ventured through various fields, from safety operations to roles he never imagined would lead him to where he stands today.
|
||||
|
||||
> "Discovering Appwrite was a turning point, where my past experiences perfectly blended into my role here.”
|
||||
>
|
||||
|
||||
Despite his unfamiliarity with the tech environment, Appwrite's mission quickly captivated him.
|
||||
|
||||
> "It’s more intriguing than I initially thought.”
|
||||
>
|
||||
|
||||
Dylan’s favorite aspect of his job is the unity and excitement of Appwrite camps, with Camp 3.0 in New York holding a special place in his heart. Despite the bureaucratic hurdles of bringing together a global team, the satisfaction of a successful camp is unmatched.
|
||||
|
||||

|
||||
|
||||
> "Organizing and planning these gatherings is what I thrive on.”
|
||||
>
|
||||
|
||||
Beyond the logistics, Dylan values the cultural insights and personal stories shared among the team.
|
||||
|
||||
> "It’s a window into worlds I’d never have encountered elsewhere.”
|
||||
>
|
||||
|
||||
The vibe at Appwrite? It's laid-back yet focused.
|
||||
|
||||
> “We're all about enjoying our work while making sure we’re hitting our goals.”
|
||||
>
|
||||
|
||||
Whether it’s putting together videos in one day or setting up a mini-camp for a handful of people in record time, the team makes it happen.
|
||||
|
||||
> “It's this blend of fun and determination that makes working here so special.”
|
||||
>
|
||||
|
||||
# The core of teamwork
|
||||
|
||||
A solid trust in teamwork is at the heart of Dylan’s philosophy and the culture of Appwrite.
|
||||
|
||||
> "There’s no one on this team I wouldn't trust."
|
||||
>
|
||||
|
||||
But this trust isn't just words. It's evident in the real improvements and new ideas that have come to life during his time here. From making it easier to request swag to simplifying travel organisation, the operations team has made changes that help Appwrite run more smoothly.
|
||||
|
||||
Dylan sums up Appwrite with three simple but powerful words: collaboration, inspiration, and fun. For him, collaboration is key.
|
||||
|
||||
> "It's all about us coming together, from different parts of the world, to do something great.”
|
||||
>
|
||||
|
||||
Appwrite is more than just a place to work. Appwrite inspires and motivates the team and people in the community to start their own projects. And despite the hard work, having fun is always part of the day.
|
||||
|
||||
> "Yes, we work hard, but making sure we all have fun doing what we love is just as important."
|
||||
>
|
||||
|
||||
Keeping Dylan on his toes is the daily challenge of his role, whether figuring out the intricacies of legal paperwork or setting up events with little notice.
|
||||
|
||||
> "It pushes me to go beyond what's comfortable and tackle something new.”
|
||||
>
|
||||
|
||||
And when things get tricky or the workload piles up, the supportive atmosphere at Appwrite really stands out.
|
||||
|
||||
> "I know I can always ask for help or clarification, no matter how many questions I have, to overcome any hurdle."
|
||||
>
|
||||
|
||||
# Remote rhythms and career crescendos
|
||||
|
||||
Navigating the remote work landscape, Dylan admits there’s a bittersweet note to not meeting teammates in person as often as he'd like.
|
||||
|
||||
> "But then, we have our twice-a-year get-togethers, which are total game-changers."
|
||||
>
|
||||
|
||||
Swapping office life for the flexibility of remote work hasn't slowed him down. In fact, it’s opened up new possibilities. Now, he gets to blend work with personal activities, like hitting the gym whenever he feels like it.
|
||||
|
||||
> "Honestly, the upsides are way too good."
|
||||
>
|
||||
|
||||
Dylan’s pro tip for remote work? Treat communication tools as your virtual office space and keep the chats flowing.
|
||||
|
||||
> "It makes everything feel more connected and a lot less isolated."
|
||||
>
|
||||

|
||||
|
||||
His ascent to operations leader was unexpected but embraced. Initially stepping in as a temporary fix, it wasn't long before the opportunity to lead became permanent, thanks to Eldad's vote of confidence.
|
||||
|
||||
> "I'm really grateful and excited about where my career's headed.”
|
||||
>
|
||||
|
||||
Looking ahead, he's planning to take an accounting course to broaden his skill set, a step towards understanding the financial aspects of his role better.
|
||||
|
||||
To those dreaming of joining the team, Dylan’s advice is refreshingly straightforward:
|
||||
|
||||
> "Just be yourself."
|
||||
>
|
||||
|
||||
In the world of Appwrite, being genuine beats everything else. We’re all about keeping it real and valuing honesty way more than just seeming perfect.
|
||||
|
||||
> "No need for masks, start as you mean to go on: genuine and straightforward."
|
||||
>
|
||||
|
||||
For those looking into the operations side of things, Dylan can’t stress enough how important it is to be friendly and effective at getting your point across.
|
||||
|
||||
> "Sure, the to-do list can get pretty long, but the feeling of nailing it? Unbeatable."
|
||||
>
|
||||
|
||||
He believes in taking your time and being naturally curious.
|
||||
|
||||
> "Chaos comes with the territory. But don’t let it stop you from asking all the questions you need."
|
||||
>
|
||||
|
||||
From embracing the remote work lifestyle to leading operations with curiosity and openness, Dylan reflects what Appwrite is all about. His story is a testament to the strength of authenticity, the importance of teamwork, and the endless possibilities that come from saying “yes” to challenges and growth. For Dylan, Appwrite isn’t just a workplace. It’s a platform for personal and professional evolution, where every day is a new adventure.
|
||||
|
||||
If you’re looking to learn more about Dylan or connect with him, visit his social profiles:
|
||||
|
||||
- [LinkedIn](https://www.linkedin.com/in/dylang64/)
|
||||
107
src/routes/blog/post/baas-vs-custom-backend/+page.markdoc
Normal file
@@ -0,0 +1,107 @@
|
||||
---
|
||||
layout: post
|
||||
title: "BaaS vs. Custom Backend: making the right choice as a freelancer"
|
||||
description: Discover whether BaaS or a custom backend is the best fit for your freelance projects. In this blog we weigh the pros and cons to help you make the right choice.
|
||||
cover: /images/blog/baas-vs-custom-backend/cover.png
|
||||
timeToRead: 6
|
||||
date: 2024-06-20
|
||||
author: aditya-oberai
|
||||
category: product
|
||||
---
|
||||
|
||||
As a freelance developer, you juggle multiple roles – project manager, designer, coder, and even a bit of a salesperson. The job is not for the faint of heart. Add to that the need to build, scale and maintain complex backends for each client, and now your day-to-day is taken over by time-consuming, grinding tasks.
|
||||
|
||||
This is where Backend-as-a-Service (BaaS) comes in. BaaS abstracts away backend complexity, allowing you to deliver an elevated product without getting bogged down in the repetitiveness of server-side development. And often, a BaaS can be a game-changer for freelance developers.
|
||||
|
||||
# What is a BaaS?
|
||||
|
||||
Backend-as-a-Service (BaaS) is a third-party service that lets developers delegate common backend operations of a web or mobile application. Such operations include but are not limited to:
|
||||
|
||||
- User Authentication
|
||||
- Database Management
|
||||
- Push Notifications
|
||||
- File Storage
|
||||
- Hosting
|
||||
|
||||
Implementing these from scratch is quite tedious and repetitive, especially if you’re making multiple apps for multiple clients. These tasks take focus away from what you do best: inventing creative and functional solutions that bring value to your client.
|
||||
|
||||
BaaS providers take care of the boring stuff, which makes them an attractive solution for freelancers who want to gain back time without compromising on quality.
|
||||
|
||||
# BaaS vs Custom Backend
|
||||
|
||||
Custom-built backends let you tailor everything to your client’s needs. Normally, you would create the reusable components for one client, and then it's just a matter of copying and pasting. The real pain comes in maintaining them. Let's say you find a bug and fix it for one client. Now, you have to fix it for every client, copying the changes and deploying them each time. While automation could simplify this, you're already stuck in the hole you dug by reusing custom backends.
|
||||
|
||||
With a BaaS platform, you can build an entire backend in minutes. For example, you can design a database, add your data, and seamlessly communicate with a frontend using a REST API, SDK, or GraphQL. This means you can turn around projects faster, save money, and leverage reliable technologies across all your work.
|
||||
|
||||
What if you already have a library of technologies? A dedicated platform ensures they’re robust, up-to-date, and integrate well with your existing tools. This way, you can maintain the reliability and performance of your applications without the hassle of constant manual updates and compatibility checks.
|
||||
|
||||
Let's take a look at some of the most common products that backend-as-a-service providers offer. We'll use [Appwrite](https://appwrite.io/) as an example, but many BaaS vendors offer similar technologies. What makes Appwrite convenient is that it combines everything into a single open-source platform, simplifying the development process. Our philosophy is to meet you — the developer — where you are, empowering you to use the tools and technologies you love.
|
||||
|
||||
# BaaS for Authentication
|
||||
|
||||
As a freelancer, you’ve probably built more authentication systems than you want to admit. However, a tricky solution like user authentication often requires additional support and expertise. One of our software engineers, Matej Bačo, who got his start as a freelance developer, said that finding a good authentication solution was crucial: “What was the safety standard 20 years ago is considered unacceptable now. Who knows what it will be like in 10 years? A freelancer should be able to build safe and secure apps without needing to keep an eye on every security change.”
|
||||
|
||||
For example, [Appwrite Authentication](/docs/products/auth) simplifies the process to just a few clicks and a couple of lines of code. In Appwrite, you can securely authenticate users using multiple login methods, such as Email & Password, SMS, OAuth2, Anonymous, Magic URLs, and more. If your client requires specific authentication methods such as Auth0, tailored authentication using Web3 or AI, or integration with company-specific hardware cards, custom tokens let you implement your own authentication flow to meet these needs. There’s also support for teams, roles, and user labels, and includes rate-limiting and advanced user protection features.
|
||||
|
||||

|
||||
|
||||
You also get 30+ OAuth2 integrations. From Google and Github to Twitch and Yandex, you can set up your user auth in minutes – quite literally!
|
||||
|
||||
[Take a look at how Dennis Ivy set up Google OAuth sign-in in less than 6 minutes using Appwrite.](https://youtu.be/tgO_ADSvY1I?feature=shared)
|
||||
|
||||
Additionally, BaaS handles password recovery, multi-factor authentication and other security aspects, giving you peace of mind and allowing you to focus on building great apps instead of worrying about [authentication and security issues.](/blog/post/goodbye-plaintext-passwords) For example, with a custom backend, you'll probably need a custom database, custom authorization store, and validator — lots of work in a feature where even the smallest mistake is critical.
|
||||
|
||||
With a BaaS like Appwrite, it's as simple as clicking a few checkboxes.
|
||||
|
||||
# BaaS for Databases
|
||||
|
||||
Database management is challenging even for the most experienced developer. While storing data may be pretty straightforward, making your database fast and high-performing is where most spend ages.
|
||||
|
||||
BaaS providers offer pre-configured database solutions, allowing you to quickly set up and manage databases without spending time on complex configurations and deploying to Cloud.
|
||||
|
||||
The beauty of [Appwrite Databases](/docs/products/databases) is that it simplifies database management with a user-friendly interface. This makes it easier for developers to perform tasks like data storage, retrieval, and backup without deep expertise.
|
||||
|
||||

|
||||
|
||||
If you require a more specific functionality, you can integrate [any external database into your Appwrite project, such as SQL, NoSQL, Vector, Graph, and more](/blog/post/integrate-sql-nosql-vector-graph-or-any-database-into-your-appwrite-project) – there’s absolutely no vendor lock-in.
|
||||
|
||||
By delegating database management to a BaaS, you can focus on enhancing core application features and user experience, free from repetitive backend tasks.
|
||||
|
||||
# BaaS for Cloud Storage
|
||||
|
||||
Dealing with the complexities of cloud infrastructure takes valuable time and focus from innovating solutions.
|
||||
|
||||
With BaaS platforms, you get a friendly interface to tap into the powerhouses of cloud services like AWS, Google Cloud, or Azure, all at warp speed. As a freelance developer, you get easy-to-use APIs and SDKs that allow you to integrate cloud storage functionality into their applications quickly, without building complex storage infrastructure from scratch.
|
||||
|
||||
For example, [Appwrite Storage](/docs/products/storage) lets you securely store files with advanced compression, encryption and image transformations. You can edit, crop and resize images straight from the console. The feature also includes access controls, and data backups to protect stored data from unauthorized access, data loss, or breaches. No need to worry about security!
|
||||
|
||||
Additionally, you can upload files as they are or in chunks for better speeds, ensuring a smoother experience. Plus, if a user's internet goes down during an upload, resumable uploads allow them to re-upload only the missing parts, saving time and frustration.
|
||||
|
||||

|
||||
|
||||
Security features let you control allowed file formats and set maximum sizes for specific features. For slow (usually mobile) networks, Appwrite optimizes uploads by converting images to WEBP or lowering quality and resolution, ensuring fast and efficient performance.
|
||||
|
||||
Appwrite’s pricing model makes it easy to scale your project without the upfront costs associated with setting up and managing dedicated storage servers. Alternatively, you can always choose self-hosting if pricing were ever to get out of hands.
|
||||
|
||||
# BaaS for Messaging
|
||||
|
||||
Messaging is hard to home brew – it requires expertise in designing and implementing fault-tolerant systems, scalable architectures, robust security measures, and more. While building from scratch offers customization, it demands significant time, effort, and resources. Many freelance developers opt for existing messaging platforms or Backend-as-a-Service solutions to save time and money.
|
||||
|
||||
In [Appwrite Messaging](/docs/products/messaging), with just a few lines of backend code, you can set up a full-functioning messaging service for your application that covers email, SMS, and push notifications under one unified API. It supports a variety of third-party messaging services:
|
||||
|
||||

|
||||
|
||||
You can group your users by topic, user type or target, and draft messages directly inside the Appwrite Console. Drafting directly in the Appwrite Console is great for promo messages, newsletters, and other announcements. You can see a preview of what your message will look like right in the console and control how your message will look before sending.
|
||||
|
||||
Additionally, you can schedule messages, set up real-time alerts and send automated emails, all from the console.
|
||||
|
||||
# Making the right choice as a freelance developer
|
||||
|
||||
For a freelance developer, time is quite literally money. If you want to maximize your time, you must find ways to work smart, not hard. Choosing a BaaS instead of building your own backend can save you tons of time and money, all while delivering a better product. With a BaaS like [Appwrite](https://appwrite.io/), you can quickly roll out effective solutions for multiple clients, ensuring your apps are robust and scalable. And if anything were ever to change, you can always migrate your project elsewhere — there’s no vendor lock-in.
|
||||
|
||||
Plus, Appwrite has an awesome community of developers who are ready to help. If you want to enhance your efficiency and project quality, explore Appwrite today.
|
||||
|
||||
- [Get started](https://cloud.appwrite.io/)
|
||||
- [Join the Discord community](https://appwrite.io/discord)
|
||||
- [Explore docs](/docs)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
layout: post
|
||||
title: Building cross platform applications with React Native
|
||||
title: How to build cross-platform applications with React Native
|
||||
description: With the launch of our new React Native SDK in open beta we want to take a deeper dive into cross platform development and when you should use it.
|
||||
date: 2024-05-05
|
||||
cover: /images/blog/react-nativecross.png
|
||||
@@ -9,11 +9,11 @@ author: damodar-lohani
|
||||
category: engineering
|
||||
---
|
||||
|
||||
Android, iOS, macOS, Linux, Windows, and the Web. Different platforms with different codebases. As a developer, you might have faced the challenge of building one application for multiple platforms. Considering the challenge of mastering all of the skills to build an application that performs well cross-platform, it’s no wonder we have seen the rise of cross platform frameworks such as React Native and Flutter. Frameworks that allow you to create applications that operate seamlessly across multiple operating systems from a single codebase. Saving time, cutting costs, and targeting a larger user base.
|
||||
Android, iOS, macOS, Linux, Windows, and the Web. Different platforms with different codebases. As a developer, you might have faced the challenge of building one application for multiple platforms. Considering the challenge of mastering all of the skills to build an application that performs well cross-platform, it’s no wonder we have seen the rise of cross platform frameworks such as React Native and Flutter. These frameworks allow you to create applications that run smoothly on multiple operating systems from a single codebase. This saves time, reduces costs, and reaches a larger user base.
|
||||
|
||||
# Why cross platform?
|
||||
# Why cross-platform?
|
||||
|
||||
Why might one choose cross platform development over developing applications for each platform? Based on the intro, it might seem logical, but let’s take a deeper look at why this is beneficial in some cases.
|
||||
Why might one choose cross-platform development over developing applications for each platform? Based on the intro, it might seem logical, but let’s take a deeper look at why this is beneficial in some cases.
|
||||
|
||||
There might be several reasons, but the most important ones are as follows:
|
||||
|
||||
@@ -48,7 +48,7 @@ Finally, when the application needs to handle native device-specific functionali
|
||||
|
||||
# Try React Native for your next project
|
||||
|
||||
There are many great cross-platform framework technologies, like [Flutter](https://appwrite.io/docs/quick-starts/flutter), .NET MAUI, Ionic, and more. Each cross-platform frameworks have their advantages and disadvantages and we are not here to say one is better. Which framework to choose depends on one’s preference, previous knowledge and skill set, project requirements, and more. But to celebrate the release of the [Appwrite React Native SDK](https://github.com/appwrite/sdk-for-react-native) in open beta, we want to share a few points that make React Native an attractive choice.
|
||||
There are many great cross-platform framework technologies, like [Flutter](/docs/quick-starts/flutter), .NET MAUI, Ionic, and more. Each cross-platform frameworks have their advantages and disadvantages and we are not here to say one is better. Which framework to choose depends on one’s preference, previous knowledge and skill set, project requirements, and more. But to celebrate the release of the [Appwrite React Native SDK](https://github.com/appwrite/sdk-for-react-native) in open beta, we want to share a few points that make React Native an attractive choice.
|
||||
|
||||
- Learn once, write anywhere: If you already know JavaScript and React, you can easily learn and start using React Native. So, this is already an attractive choice for JavaScript developers, and it might be the one framework with the easiest learning curve
|
||||
- Native performance: React native communicates with native platform components directly, which leads to a responsive user experience close to native performance
|
||||
@@ -58,13 +58,13 @@ There are many great cross-platform framework technologies, like [Flutter](https
|
||||
|
||||
# Get started with React Native and Appwrite
|
||||
|
||||
React Native allows you to create applications that run on multiple operating systems from a single codebase, whereas Appwrite provides you with a full-functioning backend with just a few lines of code. This means that you can build a full functioning app, targetting users across iOS, Android, Mac OS, Linux, Windows, and the Web, and cut down your development time tremendously.
|
||||
React Native allows you to create applications that run on multiple operating systems from a single codebase, whereas Appwrite provides you with a full-functioning backend with just a few lines of code. This means that you can build a full functioning app, targetting users across iOS, Android, Mac OS, Linux, Windows, and the Web, and cut down your development time tremendously.
|
||||
|
||||
To get started, follow these steps.
|
||||
|
||||
## Step 1: Set up Appwrite
|
||||
|
||||
First, you must set up an Appwrite project. To do so, you must either [create an Appwrite Cloud account](https://cloud.appwrite.io) or [self-host Appwrite](https://appwrite.io/docs/advanced/self-hosting) on your system.
|
||||
First, you must set up an Appwrite project. To do so, you must either [create an Appwrite Cloud account](https://cloud.appwrite.io) or [self-host Appwrite](/docs/advanced/self-hosting) on your system.
|
||||
|
||||

|
||||
|
||||
@@ -83,7 +83,7 @@ npx expo install react-native-appwrite react-native-url-polyfill
|
||||
|
||||
## Step 3: Explore the Documentation
|
||||
|
||||
Familiarize yourself with [Appwrite's documentation](https://appwrite.io/docs). It's packed with tutorials, examples, and API references designed to get you up to speed in no time.
|
||||
Familiarize yourself with [Appwrite's documentation](/docs). It's packed with tutorials, examples, and API references designed to get you up to speed in no time.
|
||||
|
||||
## Step 4: Start Building
|
||||
|
||||
@@ -98,7 +98,7 @@ client
|
||||
.setEndpoint('http://cloud.appwrite.io/v1') // Your Appwrite Endpoint
|
||||
.setProject('455x34dfkj') // Your project ID
|
||||
.setPlatform('com.example.myappwriteapp'); // Your application ID or bundle ID
|
||||
|
||||
|
||||
const account = new Account(client);
|
||||
|
||||
// Register a user
|
||||
@@ -110,14 +110,14 @@ account.create(ID.unique(), 'me@example.com', 'password', 'Jane Doe')
|
||||
});
|
||||
```
|
||||
|
||||
Read the [quick start](http://appwrite.io/docs/quick-starts/react-native) to get started or find a [tutorial](http://appwrite.io/docs/tutorials/react-native/step-1) to build an ideas tracker with React Native.
|
||||
Read the [quick start](/docs/quick-starts/react-native) to get started or find a [tutorial](/docs/tutorials/react-native/step-1) to build an ideas tracker with React Native.
|
||||
|
||||
# Resources
|
||||
|
||||
Visit our documentation to learn more about our SDKs, join us on Discord to be part of the discussion, view our blog and YouTube channel, or visit our GitHub repository to see our source code.
|
||||
|
||||
- [Docs](https://appwrite.io/docs/sdks)
|
||||
- [Docs](/docs/sdks)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
- [GitHub](https://github.com/appwrite/appwrite)
|
||||
|
||||
@@ -74,7 +74,7 @@ Lastly, we added **collection-level permissions** to allow anyone to read data (
|
||||
Looking at the two primary features, there were three primary challenges we needed to solve to develop this app. To build this app, we used SvelteKit, a framework to build web applications using JavaScript. There are some prerequisites, however, that must be completed before building out the features themselves.
|
||||
|
||||
> Note: The code snippets will focus only on the application logic. All CSS and styling-related information will be accessible in the final project repository at the end of the blog.
|
||||
>
|
||||
>
|
||||
|
||||
### Prerequisites
|
||||
|
||||
@@ -384,4 +384,4 @@ The giveaway roulette app was used over 450 times by 230+ different users across
|
||||
|
||||
You can find the application’s complete source code at this [GitHub Repo](https://github.com/adityaoberai/InitGiveawayRoulette).
|
||||
|
||||
[Join us on Discord](http://appwrite.io/discord) to be the first to get updates and to be part of a vibrant community!
|
||||
[Join us on Discord](https://appwrite.io/discord) to be the first to get updates and to be part of a vibrant community!
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
---
|
||||
layout: post
|
||||
title: Building with Appwrite AI Function templates
|
||||
description: Get an overview of Appwrite AI Function templates and what you can build.
|
||||
date: 2024-05-16
|
||||
cover: /images/blog/building-with-ai-function-templates/function-templates.png
|
||||
timeToRead: 7
|
||||
author: aditya-oberai
|
||||
category: product
|
||||
---
|
||||
|
||||
It’s an exciting time for software development, as many new concepts and techniques pop up every day, giving us endless possibilities to build new and shiny things. But this sea of opportunity can be hard to navigate and keep up with. AI, for instance, is a field that is rapidly evolving and is influencing not only the products we can build but also the way we develop them. However, building AI-powered applications can be complicated. Appwrite’s new AI Function templates make it easier to build AI powered applications.
|
||||
|
||||
So, what did we add? This blog provides an overview of all the concepts we’ve added, tutorials, templates, and the integrations we support.
|
||||
|
||||
# Computer vision
|
||||
|
||||
[Computer vision](https://appwrite.io/blog/post/state-of-computer-vision) is a field of AI aiming to provide machines with a comprehensive understanding of visual data from a variety of sources. Two sub techniques we added support for are image classification and object detection. Both techniques are widely used in our day to day lives, let’s take a look.
|
||||
|
||||
## Image classification
|
||||
|
||||
Image classification is a process used in machine learning and artificial intelligence to categorize images into different groups based on their content. It’s a technique that serves many use cases, such as:
|
||||
|
||||
1. **Healthcare**: In the medical field, image classification is used to analyze medical images, such as X-rays, MRIs, and CT scans, to detect and diagnose diseases. For example, AI can identify patterns in imaging that may indicate tumors, fractures, or other abnormalities.
|
||||
2. **Autonomous vehicles**: Self-driving cars use image classification to understand their surroundings. Cameras capture images that the system classifies in real-time to identify road signs, pedestrians, other vehicles, and various obstacles to navigate safely.
|
||||
3. **Retail**: Image classification can automate inventory management by identifying products on shelves. It's also used in visual search systems, allowing customers to search for products by uploading images instead of using text-based queries.
|
||||
|
||||
## Function templates added to the Console
|
||||
|
||||
- Image Classification - Classify images using the Hugging Face inference API.
|
||||
|
||||
## Tutorial
|
||||
|
||||
{% cards %}
|
||||
{% cards_item href="/docs/products/ai/tutorials/image-classification" title="Image classification" %}
|
||||
Understand and label the contents of images
|
||||
{% /cards_item %}
|
||||
{% /cards %}
|
||||
|
||||
## Object detection
|
||||
|
||||
Object detection is a technology used in computer vision that not only categorizes images but also identifies and locates multiple objects within a single image. It's a step beyond basic image classification because it involves not just identifying what objects are present in an image, but also pinpointing their specific boundaries (usually through bounding boxes). The technique has made many media appearances, and companies like Tesla and Apple have widely used it in their products. Some examples:
|
||||
|
||||
1. **Autonomous driving**: Object detection is critical for autonomous vehicles to interpret their surroundings accurately. It helps cars detect and localize objects like pedestrians, other vehicles, traffic lights, and road signs, facilitating safe navigation and decision-making.
|
||||
2. **Face recognition**: In security and surveillance, object detection is used for facial recognition systems. These systems identify and verify individuals by detecting faces in images or video streams, useful in law enforcement, secure facility access, and authentication systems.
|
||||
3. **Retail**: In retail, object detection is used for customer behavior analysis, stock management, and theft prevention. Cameras can detect when items are picked from shelves, track customer movements, and identify actions that might indicate suspicious behavior.
|
||||
|
||||
## Function templates added to the Console
|
||||
|
||||
- Object Detection - Detect objects in images using the Hugging Face inference API.
|
||||
|
||||
## Tutorial
|
||||
|
||||
{% cards %}
|
||||
{% cards_item href="/docs/products/ai/tutorials/object-detection" title="Object detection" %}
|
||||
Detect and label objects in images
|
||||
{% /cards_item %}
|
||||
{% /cards %}
|
||||
|
||||
# Natural language processing
|
||||
|
||||
[Natural language processing](https://appwrite.io/blog/post/state-of-natural-language-processing) (NLP) is a fascinating intersection of computer science, artificial intelligence, and linguistics. It's about teaching computers to understand, interpret, and generate human language. Translating languages, answering questions, or helping find information, NLP is at the heart of many technologies we use every day. Two techniques that Appwrite Function templates support are text generation and language translation.
|
||||
|
||||
## Text generation
|
||||
|
||||
Text generation, facilitated by technologies like artificial neural networks, specifically those designed for natural language processing (NLP), has a wide range of applications. The most well known applications are probably chatbots, but it supports a lot more applications you (probably) use every day:
|
||||
|
||||
1. **Personal assistants**: Digital assistants such as Siri, Alexa, and Google Assistant use text generation to converse with users, manage tasks, and provide information in a natural, conversational manner.
|
||||
2. **Coding and development**: AI-driven text generation aids developers by suggesting code completions, generating documentation, and even writing code snippets based on descriptions of functionality.
|
||||
3. **Creative writing**: AI can assist in generating creative text for stories, poetry, scripts, and even music compositions, providing a new tool for artists and writers to explore creative ideas.
|
||||
|
||||
## Function templates added to the Console
|
||||
|
||||
- Text Generation - Generate text using the Hugging Face inference API.
|
||||
- Chat - Create a chatbot using the Perplexity AI API.
|
||||
- Prompt ChatGPT - Ask questions and let OpenAI GPT-3.5-turbo answer.
|
||||
- RAG with LangChain - Generate text using a LangChain RAG model.
|
||||
|
||||
## Tutorial
|
||||
|
||||
{% cards %}
|
||||
{% cards_item href="/docs/products/ai/tutorials/text-generation" title="Text generation" %}
|
||||
Generate human-like text
|
||||
{% /cards_item %}
|
||||
{% /cards %}
|
||||
|
||||
## Language translation
|
||||
|
||||
Language translation, particularly when facilitated by advanced artificial intelligence (AI) technologies, is a crucial application of natural language processing (NLP) that serves numerous practical and essential purposes. Thanks to this technological advancement, we no longer need to master a language to order food in a foreign restaurant. Here are more use cases:
|
||||
|
||||
1. **Translation services**: Language translation is critical in machine translation services like Google Translate, which convert text from one language to another. While not perfect, these services are continually improving and are invaluable for global communication.
|
||||
2. **Education and learning**: Translation tools help students and educators access a broader range of educational materials and resources. They allow people to learn languages independently or access courses and content that are not available in their native language.
|
||||
3. **Travel and tourism**: Translation apps and devices are indispensable for travelers, helping them navigate foreign environments, read signs and menus, communicate with locals, and understand cultural nuances.
|
||||
|
||||
## Function templates added to the Console
|
||||
|
||||
- Analyze - Automate moderation by getting the toxicity of messages.
|
||||
- Language Translation - Translate text using the Hugging Face inference API.
|
||||
|
||||
## Tutorial
|
||||
|
||||
{% cards %}
|
||||
{% cards_item href="/docs/products/ai/tutorials/language-translation" title="Language translation" %}
|
||||
Translate text between languages
|
||||
{% /cards_item %}
|
||||
{% /cards %}
|
||||
|
||||
# Audio processing
|
||||
|
||||
[Audio processing](https://appwrite.io/blog/post/state-of-audio-processing) is a field of machine learning that allows machines to understand, analyze, and manipulate various audio signals. The applications are vast and varied, from speech recognition to music generation and noise reduction. It's used in many everyday tools you use, including voice assistants, music streaming services, and for noise reduction in online calls. We’ve added support for speech to recognition, text-to-speech, and even music generation.
|
||||
|
||||
## Speech to recognition
|
||||
|
||||
Speech recognition technology, which converts spoken language into text, is a vital component of modern computing interfaces and has numerous applications across various sectors. One of its most known use cases is the ability to turn speech into text messages on your phone. But who actually uses this? Here are some better use cases:
|
||||
|
||||
1. **Virtual assistants**: Devices like smartphones and smart speakers use speech recognition to enable users to interact with them through voice commands. Virtual assistants like Siri, Alexa, and Google Assistant respond to inquiries, control smart home devices, set reminders, and play music, all initiated by voice.
|
||||
2. **Accessibility**: Speech recognition significantly enhances accessibility for individuals with disabilities. It allows people who have difficulty using conventional input devices (like keyboards and mice) to interact with computers and mobile devices using their voice.
|
||||
3. **Customer service**: Many companies employ speech recognition in their customer service operations, using voice-driven interfaces to handle customer inquiries, automate responses, and route calls to appropriate departments without human intervention.
|
||||
|
||||
## Function templates added to the Console
|
||||
|
||||
- Speech Recognition - Transcribe audio to text using the Hugging Face inference API.
|
||||
|
||||
## Tutorial
|
||||
|
||||
{% cards %}
|
||||
{% cards_item href="/docs/products/ai/tutorials/speech-recognition" title="Speech recongition" %}
|
||||
Efficiently convert speech to text
|
||||
{% /cards_item %}
|
||||
{% /cards %}
|
||||
|
||||
## Text to speech
|
||||
|
||||
Text-to-speech (TTS) technology converts written text into spoken words, and these days, it has made headlines for its help in creating deep fakes. But it’s not all bad as it can be a very helpful tool for many use cases such as:
|
||||
|
||||
1. **Consumer electronics**: Many devices, including smartphones and computers, incorporate TTS to read text aloud, from navigation directions in GPS systems to operating instructions and notifications.
|
||||
2. **Telecommunications**: Companies use TTS for automated telephony systems, which help in delivering information to callers and guiding them through menu options without human intervention.
|
||||
3. **Media**: TTS technology is used in news reading apps and websites, where it can read articles to users, making content consumption possible even while multitasking.
|
||||
|
||||
## Function templates added to the Console
|
||||
|
||||
- Text to Speech - Convert text to speech using the Hugging Face inference API.
|
||||
- Speak with ElevenLabs - Convert text to speech using the ElevenLabs API.
|
||||
- Speak with LMNT - Convert text to speech using the LMNT API.
|
||||
|
||||
## Tutorial
|
||||
|
||||
{% cards %}
|
||||
{% cards_item href="/docs/products/ai/tutorials/text-to-speech" title="Text to speech" %}
|
||||
Generate music from a text prompt
|
||||
{% /cards_item %}
|
||||
{% /cards %}
|
||||
|
||||
## Music generation
|
||||
|
||||
Music generation with artificial intelligence (AI) involves using machine learning algorithms to create music, often without direct human input for composition. Although many artists are not happy with this trend, the technology is growing in popularity and applications. Here are some examples where AI generated music is used:
|
||||
|
||||
1. **Film and Video Games**: AI can generate background music and sound effects for films and video games, adapting dynamically to the visuals or gameplay to enhance the user experience without the need to compose each piece of music manually.
|
||||
2. **Music Production**: AI assists artists by generating music samples, beats, or entire compositions. Musicians can modify these AI-generated elements or use them to inspire new works. This technology is particularly helpful for artists with limited access to professional studios or expensive equipment.
|
||||
3. **Copyright-free Music Generation**: AI can generate original compositions that do not require licensing fees for creators who need copyright-free music for videos, podcasts, or other media.
|
||||
|
||||
## Function templates added to the Console
|
||||
|
||||
- Music generation - Generate music from a text prompt using the Hugging Face inference API.
|
||||
|
||||
## Tutorial
|
||||
|
||||
{% cards %}
|
||||
{% cards_item href="/docs/products/ai/tutorials/music-generation" title="Music generation" %}
|
||||
Efficiently convert text to music
|
||||
{% /cards_item %}
|
||||
{% /cards %}
|
||||
|
||||
# Getting started with AI and Appwrite
|
||||
|
||||
As we have covered in this blog, we have added a lot of great templates for you to get started on your AI journey. Including support for AI integrations:
|
||||
|
||||
- [Pinecone](https://appwrite.io/docs/products/ai/integrations/pinecone)
|
||||
- [OpenAI](https://appwrite.io/docs/products/ai/integrations/openai)
|
||||
- [Hugging Face](https://appwrite.io/docs/products/ai/tutorials/image-classification)
|
||||
- [ElevenLabs](https://appwrite.io/docs/products/ai/integrations/elevenlabs)
|
||||
- [Perplexity](https://appwrite.io/docs/products/ai/integrations/perplexity)
|
||||
- [Replicate](https://appwrite.io/docs/products/ai/integrations/replicate)
|
||||
- [fal.ai](https://appwrite.io/docs/products/ai/integrations/fal-ai)
|
||||
- [LangChain](https://appwrite.io/docs/products/ai/integrations/langchain)
|
||||
- [Together AI](https://appwrite.io/docs/products/ai/integrations/togetherai)
|
||||
|
||||

|
||||
|
||||
We've also added more AI Function templates for more use cases than discussed above:
|
||||
- Sync with Pinecone - Sync your Appwrite database with Pinecone's vector database.
|
||||
- Generate with fal.ai - Generate images using fal.ai's API.
|
||||
- Censor with Redact - Censor sensitive information from a provided text string using Redact API by Pangea.
|
||||
- Analyze with PerspectiveAPI - Automate moderation by getting toxicity of messages.
|
||||
- Generate with Replicate - Generate text, audio and images using Replicate's API.
|
||||
|
||||
Take a look at these two blogs to learn more about using Function templates in your projects:
|
||||
|
||||
- [Streamline receipt scanning with Appwrite Cloud](https://appwrite.io/blog/post/scan-receipts-with-appwrite-functions)
|
||||
- [Build an intelligent chatbot with ChatGPT and Appwrite Functions](https://appwrite.io/blog/post/function-template-prompt-chatgpt)
|
||||
|
||||
We will continue to add more AI tutorials, integrations, blogs, videos, and Function templates. You can also contribute by adding your own pull requests to the [repository](https://github.com/appwrite/templates).
|
||||
@@ -20,7 +20,7 @@ What does it actually mean to be open source as a company? It means that our cod
|
||||
|
||||
If you haven’t yet heard, Appwrite recently announced the release of version 1.5, which has brought with it numerous features and upgrades, starting with Appwrite Messaging, our new offering to simplify implementing communication and messaging services in your applications. We have also released support for Server-Side Rendering frameworks in our SDK, allowing a substantial amount of web developers in our community to build with a lot more ease. Additionally, we have introduced Two-Factor Authentication in our suite of authentication offerings to improve the security of your app’s users. We have also added support for Enums in our SDKs to improve the developer experience and added new Bun and Dart function runtimes to Appwrite Cloud, among other updates and changes.
|
||||
|
||||
You can learn more about the release by visiting the [Init website](https://appwrite.io/init).
|
||||
You can learn more about the release by visiting the [Init website](/init).
|
||||
|
||||
# Contributors’ highlight
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
layout: post
|
||||
title: SSR vs CSR with Next.js
|
||||
description: Learn the differences between SSR and CSR and how Appwrite Authentication can be leveraged with both in Next.js.
|
||||
description: Learn the differences between SSR and CSR and how Appwrite Authentication can be leveraged with both in Next.js.
|
||||
date: 2024-02-27
|
||||
cover: /images/blog/ssr-vs-csr/cover.png
|
||||
timeToRead: 10
|
||||
@@ -10,7 +10,7 @@ category: product
|
||||
featured: false
|
||||
---
|
||||
|
||||
With modern web development frameworks, the age-old debate around server-side rendering (SSR) and client-side rendering (CSR), which rendering method is more effective, has returned to the general tech community. Since Appwrite aims to enable all developers, regardless of their preferences, in this debate, we decided to research and extend our support for both paradigms. This article will explore the differences between SSR and CSR and how Appwrite Authentication can be leveraged with both in Next.js.
|
||||
With modern web development frameworks, the age-old debate around server-side rendering (SSR) and client-side rendering (CSR), which rendering method is more effective, has returned to the general tech community. Since Appwrite aims to enable all developers, regardless of their preferences, in this debate, we decided to research and extend our support for both paradigms. This article will explore the differences between SSR and CSR and how Appwrite Authentication can be leveraged with both in Next.js.
|
||||
|
||||
# How server-side and client-side rendering differ
|
||||
|
||||
@@ -50,7 +50,7 @@ For this purpose, we rely on Appwrite's server SDKs for Next.js apps, we use our
|
||||
|
||||
## Admin and Session clients
|
||||
|
||||
The first step of understanding how we initialize the client in SSR apps. In this scenario, we need to create two types of Appwrite clients:
|
||||
The first step of understanding how we initialize the client in SSR apps. In this scenario, we need to create two types of Appwrite clients:
|
||||
|
||||
- Admin client: performs admin requests using an API key.
|
||||
- Session client: performs authenticated requests on behalf of a user.
|
||||
@@ -94,7 +94,7 @@ const sessionClient = new Client()
|
||||
.setProject('<PROJECT_ID>')
|
||||
```
|
||||
|
||||
We use the session secret to authenticate a user from an API route. This can also be done at the page component level.
|
||||
We use the session secret to authenticate a user from an API route. This can also be done at the page component level.
|
||||
|
||||
```jsx
|
||||
export async function GET(request){
|
||||
@@ -105,7 +105,7 @@ export async function GET(request){
|
||||
if (session) {
|
||||
client.setSession(session.value)
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
const user = await account.get()
|
||||
return Response.json(user)
|
||||
@@ -118,8 +118,8 @@ export async function GET(request){
|
||||
# Resources
|
||||
Visit our documentation to learn more about push notifications, join us on Discord to be part of the discussion, view our blog and YouTube channel, or visit our GitHub repository to see our open-source code.
|
||||
|
||||
- [Docs](https://appwrite.io/docs/products/auth/server-side-rendering)
|
||||
- [Docs](/docs/products/auth/server-side-rendering)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
- [GitHub](https://github.com/appwrite/appwrite)
|
||||
|
||||
94
src/routes/blog/post/developer-tools-appwrite/+page.markdoc
Normal file
@@ -0,0 +1,94 @@
|
||||
---
|
||||
layout: post
|
||||
title: 12 developer tools to supercharge your Appwrite project
|
||||
description: Boost your developer experience with Appwrite using these awesome tools.
|
||||
date: 2024-06-17
|
||||
cover: /images/blog/developer-tools-appwrite/cover.png
|
||||
timeToRead: 5
|
||||
author: aditya-oberai
|
||||
category: open-source
|
||||
---
|
||||
|
||||
Any developer-focused product is only as good as the ecosystem of developer tools surrounding it. Fortunately, over the years, we have seen several outstanding tools developed by our community, as well as a few we have developed in-house to make development with Appwrite far more productive.
|
||||
|
||||
# Our favourite developer tools for Appwrite
|
||||
|
||||
## ngx-appwrite
|
||||
|
||||
ngx-appwrite is a library designed to integrate Appwrite services seamlessly into Angular 16+ applications. It acts as a wrapper around the Appwrite Web SDK, simplifying the use of Appwrite's features within Angular projects. The library enhances developer productivity by providing RxJS streams, which facilitate reactive programming patterns commonly used in Angular applications. This integration allows developers to easily implement Appwrite's backend services, such as database, authentication, and storage while leveraging Angular's powerful framework for building dynamic web applications.
|
||||
|
||||
Take a look at their [NPM package](https://www.npmjs.com/package/ngx-appwrite) and [GitHub repo](https://github.com/blackfan23/ngx-appwrite).
|
||||
|
||||
## Auth UI
|
||||
|
||||
Auth UI offers a customizable login flow for applications, featuring a user interface that can be adapted to different authentication methods in Appwrite. The customizable UI allows developers to implement login mechanisms that align with their specific application requirements, providing flexibility in user management and security configurations. This project demonstrates the versatility of Appwrite in supporting diverse authentication needs across various projects.
|
||||
|
||||
Take a look at their [live application](https://www.authui.site/) and [Built With Appwrite page](https://builtwith.appwrite.io/projects/6467cedd4502d0e29205/).
|
||||
|
||||
## adapter-appwrite
|
||||
|
||||
adapter-appwrite is a tool designed for SvelteKit that enables developers to deploy SvelteKit applications as Appwrite functions. By using adapter-appwrite, developers can leverage SvelteKit's modern web development features, such as server-side rendering and static site generation, while utilizing Appwrite Cloud's infrastructure for their backend functionalities.
|
||||
|
||||
Take a look at their [NPM package](https://www.npmjs.com/package/adapter-appwrite) and [GitHub repo](https://github.com/lukehagar/sveltekit-adapters).
|
||||
|
||||
## Appread
|
||||
|
||||
Appread is a comprehensive guide focused on self-hosting Appwrite instances. The guide covers various aspects of setting up and managing Appwrite, including installation procedures, scaling techniques, security measures, and ensuring high availability. It provides detailed instructions for deploying Appwrite on both small servers and larger Docker Swarm setups. Appread serves as a valuable resource for developers and system administrators who want to leverage Appwrite's features while maintaining control over their own infrastructure, enabling them to optimize performance and reliability.
|
||||
|
||||
Take a look at their [online guide](https://book.appread.io/).
|
||||
|
||||
## AppExpress
|
||||
|
||||
AppExpress is a lightweight framework inspired by Express.js, designed specifically for use with Appwrite Functions. It simplifies the process of creating server-like functionalities within Appwrite by offering an intuitive API for routing and middleware integration. Developers can use AppExpress to build modular and maintainable code for handling HTTP requests, developing middleware, handling caching, and other backend operations. This framework makes it easier to develop and deploy serverless applications with Appwrite, leveraging familiar concepts from Express.js while optimizing for the Appwrite ecosystem.
|
||||
|
||||
Take a look at their [GitHub repo](https://github.com/ItzNotABug/appexpress).
|
||||
|
||||
## Appwrite Utils
|
||||
|
||||
Appwrite Utils is a collection of utilities and a command-line interface (CLI) aimed at simplifying the management of Appwrite projects. It provides tools for handling data migrations, schema updates, and data conversion tasks. The utilities help streamline the process of updating and maintaining the structure of databases and other backend components in Appwrite. This toolset is particularly useful for developers who need to make systematic changes to their Appwrite projects, ensuring smooth transitions and consistency across different environments and versions.
|
||||
|
||||
Take a look at their [NPM package](https://www.npmjs.com/package/appwrite-utils) and [GitHub repo](https://github.com/ZachHandley/AppwriteUtils).
|
||||
|
||||
## AppwriteX
|
||||
|
||||
AppwriteX is a Dart package that noninvasively extends the Appwrite Dart SDK with additional features. It enhances the standard SDK's capabilities, providing more functionalities and tools for developers working with Appwrite in Dart and Flutter environments.
|
||||
|
||||
Take a look at their [Pub.dev package](https://pub.dev/packages/appwritex) and [GitHub repo](https://github.com/insightoptech/appwritex).
|
||||
|
||||
## AppwriteMigrator
|
||||
|
||||
AppwriteMigrator is a .NET CLI tool that enables a code-first approach to managing your database schema with Appwrite. This tool simplifies the process of syncing and migrating your database schema between local and remote environments, ensuring consistency across development, staging, and production setups. By facilitating schema management through code, AppwriteMigrator helps maintain the integrity and consistency of database structures across different deployment stages, making it an invaluable tool for developers working with Appwrite in .NET environments.
|
||||
|
||||
Take a look at their [NuGet package](https://www.nuget.org/packages/PinguApps.AppwriteMigrator) and [GitHub repo](https://github.com/PinguApps/AppwriteMigrator).
|
||||
|
||||
## fetch-appwrite-types
|
||||
|
||||
fetch-appwrite-types is a tool designed to generate TypeScript types from Appwrite database collections. This utility simplifies the integration of Appwrite with TypeScript projects by creating type definitions that reflect the database schema. It enhances type safety and developer experience by providing accurate type information for database operations, reducing runtime errors, and improving code quality.
|
||||
|
||||
Take a look at their [NPM package](https://www.npmjs.com/package/fetch-appwrite-types) and [GitHub repo](https://github.com/YsarocK/fetch-appwrite-types).
|
||||
|
||||
## Appwrite SDK Generator
|
||||
|
||||
The Appwrite SDK Generator is a PHP library that automates the creation of SDKs for various programming languages, such as JavaScript/TypeScript, Dart, Python, Ruby, Kotlin, Swift, and more. It uses predefined language settings and templates to generate codebases based on Appwrite’s OpenAPI specification. This tool simplifies the process of creating and maintaining Appwrite’s SDKs, ensuring they are up-to-date with the latest API changes.
|
||||
|
||||
Take a look at our [GitHub repo](https://github.com/appwrite/sdk-generator).
|
||||
|
||||
## Appwrite CLI
|
||||
|
||||
The Appwrite Command Line Interface (CLI) is a tool for managing Appwrite servers and projects from the command line. It supports various tasks such as project setup, user management, database interactions, and deployment processes. The CLI facilitates automation and streamlines development workflows, making it easier for developers to interact with Appwrite services.
|
||||
|
||||
Take a look at our [documentation](/docs/tooling/command-line/installation).
|
||||
|
||||
## Appwrite Playgrounds
|
||||
|
||||
The Appwrite Playgrounds are a collection of simple example projects that help developers get started with Appwrite in various programming languages and frameworks. These playgrounds include setups for web, Python, React Native, Flutter, Android, PHP, Node.js, Dart, .NET, Kotlin, Swift, Ruby, Apple UIKit, Apple SwiftUI, and Deno. Each playground provides practical examples and boilerplate code to demonstrate how to integrate and use Appwrite's services in different environments, making it easier for developers to learn and implement Appwrite.
|
||||
|
||||
Take a look at our [GitHub repos](https://github.com/orgs/appwrite/repositories?q=playground&type=all).
|
||||
|
||||
# Want to discover more such tools and projects?
|
||||
|
||||
To explore more tools and projects that can help you build your applications quicker and better with Appwrite, visit the following links:
|
||||
|
||||
- [Built with Appwrite](https://builtwith.appwrite.io/): Discover a wide range of projects and applications that utilize Appwrite's features.
|
||||
- [Awesome Appwrite](https://github.com/appwrite/awesome-appwrite): A curated list of Appwrite-related resources, including libraries, tools, and projects.
|
||||
- [Appwrite Discord](https://discord.com/invite/appwrite): Connect with other developers and the Appwrite team for discussion, questions, and collaboration.
|
||||
@@ -81,8 +81,8 @@ account.createOAuth2Session(OAuthProvider.Apple, '[LINK_ON_SUCCESS]', '[LINK_ON_
|
||||
|
||||
Visit our documentation to learn more about Enums SDK support, join us on Discord to be part of the discussion, view our blog and YouTube channel, or visit our GitHub repository to see our open-source code.
|
||||
|
||||
- [Docs](https://appwrite.io/docs/sdks#enums)
|
||||
- [Docs](/docs/sdks#enums)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
- [GitHub](https://github.com/appwrite/appwrite)
|
||||
|
||||
@@ -10,19 +10,19 @@ category: engineering
|
||||
featured: false
|
||||
---
|
||||
|
||||
In the light of recent unsettling revelations regarding a backdoor discovered in the widely-used XZ Utils,
|
||||
a compression tool used in Linux environments, including Red Hat and Debian systems, the cyber-security landscape has been abuzz with concern.
|
||||
In the light of recent unsettling revelations regarding a backdoor discovered in the widely-used XZ Utils,
|
||||
a compression tool used in Linux environments, including Red Hat and Debian systems, the cyber-security landscape has been abuzz with concern.
|
||||
This discovery had a large potential impact on encrypted SSH connections, a backbone of secure communications in the tech world.
|
||||
|
||||
At Appwrite, ensuring the security and trust of our developers and users is paramount.
|
||||
We understand the concerns that arise from such vulnerabilities and their potential implications.
|
||||
At Appwrite, ensuring the security and trust of our developers and users is paramount.
|
||||
We understand the concerns that arise from such vulnerabilities and their potential implications.
|
||||
|
||||
It's crucial for the Appwrite community to know that Appwrite's services **remain unaffected** by the XZ Utils backdoor.
|
||||
It's crucial for the Appwrite community to know that Appwrite's services **remain unaffected** by the XZ Utils backdoor.
|
||||
This issue affected beta and test versions of Red Hat and Debian distributions, which Appwrite **does not use**.
|
||||
|
||||
# What does this mean for self-hosting Appwrite?
|
||||
|
||||
For our valued users who prefer the self-hosted route, leveraging Appwrite on affected operating systems (OS),
|
||||
For our valued users who prefer the self-hosted route, leveraging Appwrite on affected operating systems (OS),
|
||||
we understand your concerns. Here are our recommendations to ensure your self-hosted Appwrite instances remain secure:
|
||||
|
||||
- Immediate Update/Removal: The first and foremost step is to check if you have the affect versions (`5.6.0`,` 5.6.1`) of the XZ Utils installed. If so, downgrade to a safe version or remove the utility altogether.
|
||||
@@ -38,11 +38,11 @@ The Appwrite team has taken necessary measures to ensure that containers in our
|
||||
We also took further steps to restrict SSH access to our cloud infrastructure to reduce attack surfaces further.
|
||||
No actions are required from Appwrite Cloud developers at this time.
|
||||
|
||||
In a world where cyber threats are evolving at an alarming pace,
|
||||
In a world where cyber threats are evolving at an alarming pace,
|
||||
the Appwrite team is committed to ensuring the security and reliability of Appwrite Cloud's infrastructure,
|
||||
so you can build applications with peace of mind.
|
||||
The team will continue to monitor the situation closely, take necessary actions to mitigate any potential risks,
|
||||
and communicate any updates transparently to the community.
|
||||
|
||||
For any further questions or concerns, please reach out through [email](https://appwrite.io/contact-us) or on [Discord](https://appwrite.io/discord).
|
||||
For any further questions or concerns, please reach out through [email](/contact-us) or on [Discord](https://appwrite.io/discord).
|
||||
We're here to support you every step of the way.
|
||||
@@ -90,8 +90,8 @@ account.createOAuth2Session(OAuthProvider.Apple, '[LINK_ON_SUCCESS]', '[LINK_ON_
|
||||
|
||||
Visit our documentation to learn more about Enums SDK support, join us on Discord to be part of the discussion, view our blog and YouTube channel, or visit our GitHub repository to see our open-source code.
|
||||
|
||||
- [Docs](https://appwrite.io/docs/sdks#enums)
|
||||
- [Docs](/docs/sdks#enums)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
- [GitHub](https://github.com/appwrite/appwrite)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
layout: post
|
||||
title: See what is new with Appwrite 1.5
|
||||
description: Here is a recap off all announcements for Appwrite 1.5.
|
||||
description: Here is a recap off all announcements for Appwrite 1.5.
|
||||
date: 2024-03-05
|
||||
cover: /images/blog/everything-new-with-appwrite-1.5/1.5-recap.png
|
||||
timeToRead: 6
|
||||
@@ -86,40 +86,40 @@ You can find all the official release announcements and documentation for each d
|
||||
|
||||
- [Announcement Video](https://youtu.be/w-izHSKXqtU)
|
||||
- [Product tour](https://youtu.be/QdDgPeuBZ1I)
|
||||
- [Announcement article](https://appwrite.io/blog/post/announcing-appwrite-messaging)
|
||||
- [Docs](https://appwrite.io/docs/products/messaging)
|
||||
- [Announcement article](/blog/post/announcing-appwrite-messaging)
|
||||
- [Docs](/docs/products/messaging)
|
||||
|
||||
### Day 1: SSR
|
||||
|
||||
- [Announcement Video](https://youtu.be/jeL4cSovOBA)
|
||||
- [Product tour](https://youtu.be/7LN05c-ov_0)
|
||||
- [Announcement article](https://appwrite.io/blog/post/introducing-support-for-server-side-rendering)
|
||||
- [Docs](https://appwrite.io/docs/products/auth/server-side-rendering)
|
||||
- [Announcement article](/blog/post/introducing-support-for-server-side-rendering)
|
||||
- [Docs](/docs/products/auth/server-side-rendering)
|
||||
|
||||
### Day 2: 2FA & Enum SDK support
|
||||
|
||||
- [Announcement Video](https://youtu.be/hpdUXOFay4M) - 2FA
|
||||
- [Product tour](https://youtu.be/OWRju8ZZuQ8) - 2FA
|
||||
- [Announcement article](https://appwrite.io/blog/post/announcing-two-factor-authentication) - 2FA
|
||||
- [Announcement article - Enum SDK support](https://appwrite.io/blog/post/introducing-enum-sdk-support)
|
||||
- [Docs - 2FA](https://appwrite.io/docs/products/auth/2fa)
|
||||
- [Docs - Enum SDK support](https://appwrite.io/docs/sdks#enums)
|
||||
- [Announcement article](/blog/post/announcing-two-factor-authentication) - 2FA
|
||||
- [Announcement article - Enum SDK support](/blog/post/introducing-enum-sdk-support)
|
||||
- [Docs - 2FA](/docs/products/auth/mfa)
|
||||
- [Docs - Enum SDK support](/docs/sdks#enums)
|
||||
|
||||
### Day 3: Database Operators
|
||||
|
||||
- [Announcement Video](https://youtu.be/73flN6mZqAs)
|
||||
- [Product tour](https://youtu.be/IMgl9f_iht4)
|
||||
- [Announcement article](https://appwrite.io/blog/post/introducing-new-database-operators)
|
||||
- [Docs](https://appwrite.io/docs/products/databases/queries)
|
||||
- [Announcement article](/blog/post/introducing-new-database-operators)
|
||||
- [Docs](/docs/products/databases/queries)
|
||||
|
||||
### Day 4: New runtimes
|
||||
|
||||
- [Announcement article](https://appwrite.io/blog/post/introducing-enum-sdk-support)
|
||||
- [Docs](https://appwrite.io/docs/products/functions/runtimes)
|
||||
- [Announcement article](/blog/post/introducing-enum-sdk-support)
|
||||
- [Docs](/docs/products/functions/runtimes)
|
||||
|
||||
Join us on Discord to be part of the discussion, view our blog and YouTube channel, or visit our GitHub repository to see our open-source code.
|
||||
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
- [GitHub](https://github.com/appwrite/appwrite)
|
||||
|
||||
@@ -48,7 +48,7 @@ Benefits of password hashing compared to storing passwords in plaintext include:
|
||||
- **Mitigation of reuse attacks**: Hashed passwords make it harder for attackers to use stolen credentials on other sites, reducing the impact of credential reuse attacks.
|
||||
- **Scalability and future-proofing**: Hashing algorithms can be updated and strengthened over time, providing flexibility as security standards evolve.
|
||||
|
||||
You can read our [blog on password hashing algorithms](https://appwrite.io/blog/post/password-hashing-algorithms) to learn more.
|
||||
You can read our [blog on password hashing algorithms](/blog/post/password-hashing-algorithms) to learn more.
|
||||
|
||||
## Passwordless authentication
|
||||
|
||||
@@ -62,11 +62,11 @@ Some common passwordless authentication methods are:
|
||||
- **Authentication apps**: Generates time-based codes or push notifications for user approval.
|
||||
- **Smart cards and security tokens**: Physical devices that the user must possess to gain access.
|
||||
|
||||
You can read our [blog on passwordless authentication](https://appwrite.io/blog/post/improve-ux-passwordless-auth) to learn more.
|
||||
You can read our [blog on passwordless authentication](/blog/post/improve-ux-passwordless-auth) to learn more.
|
||||
|
||||
# How Appwrite solves this problem
|
||||
|
||||
[Appwrite Authentication](https://appwrite.io/docs/products/auth) makes building secure and robust authentication easy and supports many authentication methods. Currently, the following authentication methods are available on Appwrite to combat plaintext passwords:
|
||||
[Appwrite Authentication](/docs/products/auth) makes building secure and robust authentication easy and supports many authentication methods. Currently, the following authentication methods are available on Appwrite to combat plaintext passwords:
|
||||
|
||||
- Email and password login with `Argon2id` password hashing
|
||||
- OTP-based login via SMS and email
|
||||
@@ -76,7 +76,7 @@ You can read our [blog on passwordless authentication](https://appwrite.io/blog/
|
||||
- Custom token login to allow integration with any external authentication solution of your choice
|
||||
- Two-factor authentication to add an additional layer of security to user accounts
|
||||
|
||||
Additionally, to prevent unauthorized data access, Appwrite features a [robust permissions system](https://appwrite.io/docs/advanced/platform/permissions) that is thoroughly coupled with Appwrite Authentication. The most significant benefit of Appwrite’s permissions system is that any developer needs to offer read or write access to any user intentionally. No default rule provides open access to your application’s client, and the process of setting permissions is simplified by using Appwrite’s console UI.
|
||||
Additionally, to prevent unauthorized data access, Appwrite features a [robust permissions system](/docs/advanced/platform/permissions) that is thoroughly coupled with Appwrite Authentication. The most significant benefit of Appwrite’s permissions system is that any developer needs to offer read or write access to any user intentionally. No default rule provides open access to your application’s client, and the process of setting permissions is simplified by using Appwrite’s console UI.
|
||||
|
||||
Appwrite also enforces the setting of authorized clients to communicate with an Appwrite project for all supported client platforms (web, Android, Apple, and Flutter). This way, no unauthorized clients can access data, adding an extra layer of protection.
|
||||
|
||||
@@ -84,4 +84,4 @@ Appwrite also enforces the setting of authorized clients to communicate with an
|
||||
|
||||
No matter what rules and systems any platform provides, combating plaintext passwords is a responsibility shared by all application developers. If you, as a developer, care about the security and privacy of your user accounts and data, you must take the necessary actions to safeguard their authentication information. Appwrite takes this problem very seriously and will continue to add new tools and improve our existing ones to make user authentication simpler and safer for all developers and their users.
|
||||
|
||||
Learn more about Appwrite Authentication through our [docs](https://appwrite.io/docs/products/auth) and join our [Discord server](https://appwrite.io/discord).
|
||||
Learn more about Appwrite Authentication through our [docs](/docs/products/auth) and join our [Discord server](https://appwrite.io/discord).
|
||||
@@ -11,7 +11,7 @@ category: hacktoberfest
|
||||
|
||||
**October** is our favorite month of the year because it brings with it **Hacktoberfest**, the largest celebration of open source in the world! And this year, we returned to support DigitalOcean and **Hacktoberfest 2023** as a sponsor to invest in the upliftment of the open-source world and to rejoice the 10th anniversary of this wonderful initiative. Hacktoberfest brought moments of nostalgia seeing developers from different walks of life join in to take their first steps in the open-source world.
|
||||
|
||||
We had an absolute blast interacting with all the new contributors and hosting all the events throughout the month! Our **[Discord server](https://appwrite.io/discord)** was full of **AMAs** and **PR Review parties**, which enabled us to demonstrate our PR review workflow and allowed the community to really appreciate the work that goes into maintaining open-source projects. We were also able to educate new contributors on various facets of open source, usage of tools like Git and GitHub, the process of submitting a PR, communication best practices, and so much more!
|
||||
We had an absolute blast interacting with all the new contributors and hosting all the events throughout the month! Our **[Discord server](https://appwrite.io/discord)** was full of **AMAs** and **PR Review parties**, which enabled us to demonstrate our PR review workflow and allowed the community to really appreciate the work that goes into maintaining open-source projects. We were also able to educate new contributors on various facets of open source, usage of tools like Git and GitHub, the process of submitting a PR, communication best practices, and so much more!
|
||||
|
||||
Not only did we see multiple virtual events, but we also hosted an [in-person Hacktoberfest Kickoff meetup](https://photos.app.goo.gl/n5YQjK56CCgqyrj68) in collaboration with DigitalOcean in Bengaluru, India. Overall, this Hacktoberfest was one of the most wholesome and fulfilling experiences for our team, and we cannot wait to share our highlights from this edition.
|
||||
|
||||
@@ -28,13 +28,13 @@ That one month truly enabled us to lay the foundations of a budding organization
|
||||
This Hacktoberfest, we focused on collaborating with our contributors to make impactful contributions. Some of them really stood out to us, and we thought to share them here for you to check out too!
|
||||
|
||||
- [Security Scans in the CI pipeline using GitLeaks](https://github.com/appwrite/appwrite/pull/6492)
|
||||
|
||||
|
||||
- [Functions template to implement Sync with MeiliSearch in Kotlin](https://github.com/appwrite/templates/pull/234)
|
||||
|
||||
|
||||
- [Messaging adapter for Postmark](https://github.com/utopia-php/messaging/pull/26)
|
||||
|
||||
|
||||
- [Storage adapter for IBM Cloud Object Storage](https://github.com/utopia-php/storage/pull/90)
|
||||
|
||||
|
||||
- [Unit tests for the Android and Kotlin SDKs](https://github.com/appwrite/sdk-generator/pull/729)
|
||||
|
||||
The Appwrite team also participated in a number of livestreams throughout the month.
|
||||
@@ -58,12 +58,12 @@ All these achievements were made possible through the strong collaboration and a
|
||||
|
||||
## What’s next for Appwrite
|
||||
|
||||
We have a lot of exciting features that we’re working towards as we gear up to make **Appwrite Cloud** generally available. Appwrite Cloud is the hosted Appwrite solution managed by our team, so developers like you can focus on building their applications. We’re currently running Appwrite Cloud in Public Beta, so [sign up and start building](https://cloud.appwrite.io/register) as soon as you can!
|
||||
We have a lot of exciting features that we’re working towards as we gear up to make **Appwrite Cloud** generally available. Appwrite Cloud is the hosted Appwrite solution managed by our team, so developers like you can focus on building their applications. We’re currently running Appwrite Cloud in Public Beta, so [sign up and start building](https://cloud.appwrite.io/register) as soon as you can!
|
||||
|
||||
Besides that, this Hacktoberfest, one new product that we saw a number of folks contribute to is **Appwrite Messaging**. Stay tuned for more information on the same.
|
||||
|
||||
## How can you contribute after Hacktoberfest?
|
||||
|
||||
Hacktoberfest may be over, but you don’t have to stop contributing! We have **lots of open issues** that you can find on our [GitHub repos](https://github.com/appwrite/appwrite/issues). You can also **write articles**, **create tutorials**, or **build demo apps** and add them to our [Awesome Appwrite repo](https://github.com/appwrite/awesome-appwrite) and the [Built With Appwrite website](https://builtwith.appwrite.io). There are always new ways to support the [community](https://appwrite.io/community), and we truly love all the contributions you make. If you need help with Appwrite or would like to explore some interesting ways to contribute, join us on our [Discord server](https://appwrite.io/discord) and connect with the Appwrite community.
|
||||
Hacktoberfest may be over, but you don’t have to stop contributing! We have **lots of open issues** that you can find on our [GitHub repos](https://github.com/appwrite/appwrite/issues). You can also **write articles**, **create tutorials**, or **build demo apps** and add them to our [Awesome Appwrite repo](https://github.com/appwrite/awesome-appwrite) and the [Built With Appwrite website](https://builtwith.appwrite.io). There are always new ways to support the [community](/community), and we truly love all the contributions you make. If you need help with Appwrite or would like to explore some interesting ways to contribute, join us on our [Discord server](https://appwrite.io/discord) and connect with the Appwrite community.
|
||||
|
||||
Thank you so much once again for joining us during Hacktoberfest. We hope you enjoyed contributing to open source as much as we do, and we can’t wait to have you all with us next year!
|
||||
@@ -203,4 +203,4 @@ You can find the entire source code for the tickets on [GitHub](https://github.c
|
||||
|
||||
Although Init is over, you can still get yourself a ticket at [appwrite.io/init/tickets](/init/tickets)
|
||||
|
||||
[Join us on Discord](http://appwrite.io/discord) to be the first to get updates and to be part of a vibrant community!
|
||||
[Join us on Discord](https://appwrite.io/discord) to be the first to get updates and to be part of a vibrant community!
|
||||
|
||||
@@ -60,7 +60,7 @@ While the benefits are substantial, passwordless authentication isn't without it
|
||||
|
||||
# Implementing passwordless authentication using Appwrite
|
||||
|
||||
Appwrite Authentication also features three commonly used passwordless authentication methods: [**magic links**](https://appwrite.io/docs/products/auth/magic-url), [**email OTPs**](https://appwrite.io/docs/products/auth/email-otp), and [**phone authentication**](https://appwrite.io/docs/products/auth/phone-sms), which can be integrated into applications seamlessly with Appwrite’s client-side SDKs. This approach not only enhances security but also significantly improves the user experience by simplifying and streamlining the login process.
|
||||
Appwrite Authentication also features three commonly used passwordless authentication methods: [**magic links**](/docs/products/auth/magic-url), [**email OTPs**](/docs/products/auth/email-otp), and [**phone authentication**](/docs/products/auth/phone-sms), which can be integrated into applications seamlessly with Appwrite’s client-side SDKs. This approach not only enhances security but also significantly improves the user experience by simplifying and streamlining the login process.
|
||||
|
||||
{% tabs %}
|
||||
{% tabsitem #magicurl title="Magic URLs" %}
|
||||
@@ -165,4 +165,4 @@ final session = await account.createSession(
|
||||
|
||||
Passwordless authentication stands at the forefront of a new era in digital security and user experience. My recommendation to all is to embrace the future – say goodbye to passwords and hello to a more secure, convenient digital experience.
|
||||
|
||||
Learn more about Appwrite Authentication from our [docs](https://appwrite.io/docs/products/auth) and join our [Discord community](https://appwrite.io/discord) to interact with fellow developers using the same.
|
||||
Learn more about Appwrite Authentication from our [docs](/docs/products/auth) and join our [Discord community](https://appwrite.io/discord) to interact with fellow developers using the same.
|
||||
59
src/routes/blog/post/incident-report-feb-24/+page.markdoc
Normal file
@@ -0,0 +1,59 @@
|
||||
---
|
||||
layout: post
|
||||
title: February 2024 - Incident Report
|
||||
cover: /images/blog/privacy.png
|
||||
description: In this post, we detail the incidents encountered in February 2024, including high memory usage, database restarts, repeated gateway timeouts, and executor crashes. We share our analysis, user impact, and the resolution steps taken to mitigate these issues, reinforcing our commitment to transparency and continuous improvement.
|
||||
date: 2024-03-15
|
||||
timeToRead: 3
|
||||
author: christy-jacob
|
||||
category: cloud
|
||||
featured: false
|
||||
---
|
||||
|
||||
As Appwrite Cloud continues to grow and scale, it is inevitable that we face challenges and obstacles that test the resilience of our systems and our team's ability to respond swiftly. February 2024 was no exception, as we encountered a series of incidents that put our protocols to the test. While these moments are opportunities for growth, they also remind us of the importance of transparency and communication with our community. This blog post aims to provide a detailed overview of the incidents we experienced throughout the month, including the causes, our responses, and the lessons learned. Our commitment to continuous improvement drives us to share these insights openly, reinforcing our dedication to reliability and trust.
|
||||
|
||||
## TLDR; for February 2024
|
||||
| Date | Title | Duration |
|
||||
|------------|----------------------------------------------------|------------------|
|
||||
| 2024-02-01 | High Memory Usage During Scheduled Backups | 4 hours, 6 mins |
|
||||
| 2024-02-12 | Database Restart Incident | 1 hour, 34 mins |
|
||||
| 2024-02-13 | Gateway Timeouts in Traefik Containers | 15 mins |
|
||||
| 2024-02-14 | Gateway Timeouts in Traefik Containers | 8 mins |
|
||||
| 2024-02-15 | Gateway Timeouts in Traefik Containers | 8 mins |
|
||||
| 2024-02-19 | Executor Crash and Bad Webhook | 27 mins |
|
||||
| 2024-02-21 | Gateway Timeouts in Traefik Containers | 25 mins |
|
||||
| 2024-02-24 | Gateway Timeouts in Traefik Containers | 30 mins |
|
||||
| **Total** | | **7 hours, 33 mins** |
|
||||
|
||||
|
||||
#### High Memory Usage During Scheduled Backups
|
||||
- **Date:** February 1, 2024
|
||||
- **Duration:** 4 hours and 6 minutes
|
||||
- **Summary:** High memory usage in a database cluster caused widespread impact on cloud components.
|
||||
- **Description:** A high memory usage alert was triggered for one of the database clusters, leading to unresponsive behavior that impacted critical cloud components, including Databases, API, Functions, etc. The root cause was identified as a high memory load during scheduled backups, affecting API performance for all users on the cloud.
|
||||
- **User Impact:** Projects on the affected database were impacted, and partial API performance degradation during the initial phases.
|
||||
- **Resolution and Steps Taken:** The problematic database was temporarily disconnected from the connection string, allowing for a necessary restart. After addressing the high memory usage, the database was reconnected, mitigating the issue.
|
||||
|
||||
#### Database Restart Incident
|
||||
- **Date:** February 12, 2024
|
||||
- **Duration:** 1 hour and 34 minutes
|
||||
- **Summary:** Manual restart of a database affected project APIs.
|
||||
- **Description:** An unexpected manual restart of the `database_db_fra1_self_hosted_2_0` database was triggered by an engineer, impacting all projects associated with this database. The root cause was identified as high memory usage, compounded by a scheduling error due to time zone confusion.
|
||||
- **User Impact:** Projects on the affected database experienced downtime and service disruption.
|
||||
- **Resolution and Steps Taken:** Transparent communication was maintained with affected users throughout the incident. Post-incident, measures were implemented to ensure such time zone errors are avoided in the future.
|
||||
|
||||
#### Repeated Gateway Timeouts in Traefik Containers
|
||||
- **Dates:** February 13, 14, 15, 21, & 24
|
||||
- **Duration:** Varied; a total of 86 minutes across all incidents
|
||||
- **Summary:** Multiple incidents of gateway timeouts following cloud deployments.
|
||||
- **Description:** Routine cloud deployments triggered gateway timeout errors due to a specific configuration introduced to Traefik (`--serversTransport.maxIdleConnsPerHost=-1`), affecting routing post-deployment. This issue was consistent across several incidents, impacting users' ability to access Appwrite Cloud through the API and console.
|
||||
- **User Impact:** Sporadic gateway timeout errors on the Appwrite API and console, affecting user access to Appwrite Cloud.
|
||||
- **Resolution and Steps Taken:** Immediate action involved restarting the Appwrite service to force correct container routing. The root cause was addressed by reverting the Traefik configuration change on February 25, 2024, which resolved the gateway timeout errors.
|
||||
|
||||
#### Executor Crash and Bad Webhook
|
||||
- **Date:** February 19, 2024
|
||||
- **Duration:** 27 minutes
|
||||
- **Summary:** A crash in the functions executor combined with a faulty webhook led to increased API latency and failures.
|
||||
- **Description:** The system experienced a crash in one of its executors, triggered by a faulty webhook. This incident was compounded by a high load on the function executions, triggering multiple webhooks simultaneously, which blocked API workers ultimately leading to increased latency and monitors being triggered.
|
||||
- **User Impact:** Users experienced API timeouts and failed function executions, leading to service disruption.
|
||||
- **Resolution and Steps Taken:** Immediate actions included restarting the API and executor to recover from the crash. The problematic webhook was removed, and steps were taken to restart the webhook worker, ensuring pending jobs could continue to execute.
|
||||
@@ -0,0 +1,298 @@
|
||||
---
|
||||
layout: post
|
||||
title: Integrate any external authentication solution into your Appwrite project
|
||||
description: Add any custom authentication flow to your applications.
|
||||
date: 2024-05-30
|
||||
cover: /images/blog/integrate-custom-auth-sveltekit/cover.png
|
||||
timeToRead: 6
|
||||
author: aditya-oberai
|
||||
category: auth
|
||||
featured: false
|
||||
---
|
||||
|
||||
Whether we contribute to any existing software or build new one, user authentication is a fundamental feature our users need. Between email-password authentication, magic URLs, phone and email OTPs, and 30+ OAuth providers, Appwrite offers a variety of 1st-party offerings for your apps. However, every now and then, you will need an authentication solution beyond this list. Fortunately, Appwrite now offers a solution that allows developers to integrate any external authentication method with their Appwrite project.
|
||||
|
||||
Therefore, in this blog, we will learn about Appwrite’s custom token authentication solution, how it works, and how you can implement it in a SvelteKit app.
|
||||
|
||||
# What is custom token authentication?
|
||||
|
||||
Custom token authentication allows you to use one of Appwrite’s [Server SDKs](https://appwrite.io/docs/sdks#server) to generate tokens, short-lived secrets that can be exchanged for a session by a [Client SDK](https://appwrite.io/docs/sdks#client) to log in users. This allows you to code your own authentication methods using Appwrite Functions or your own server-side APIs. This can be beneficial in a number of scenarios, such as:
|
||||
|
||||
1. **Legacy system integration**: Integrate with old systems using unique authentication methods without major changes.
|
||||
2. **Custom security needs**: Implement special security features like hardware tokens or voice recognition.
|
||||
3. **External authentication providers**: Use providers like Clerk, SuperTokens, or Amazon Cognito, which Appwrite doesn’t support directly.
|
||||
4. **Advanced user authentication**: Create more sophisticated auth workflows, for example, triggering different authentication methods based on the user's location, device, or behavior.
|
||||
5. **Single Sign-On (SSO)**: Integrate with enterprise SSO solutions that use protocols like SAML or LDAP.
|
||||
6. **Migration to Appwrite**: Transition smoothly from an existing authentication system to Appwrite.
|
||||
|
||||
# Implementing custom token authentication
|
||||
|
||||
In order to implement custom token authentication in an application, you need to develop two distinct parts:
|
||||
|
||||
1. Server-side function to run the authentication flow and create a user token
|
||||
2. Client-side app to trigger the custom auth flow and create a session via the token secret
|
||||
|
||||
For the purposes of this demo application, I will be implementing these in a SvelteKit application.
|
||||
|
||||
## Pre-requisites
|
||||
|
||||
Before we implement our auth flow, we must first:
|
||||
|
||||
- Create an Appwrite project and create an API key
|
||||
- Set up a SvelteKit app on our local system
|
||||
|
||||
### Appwrite
|
||||
|
||||
First, we must create an account on [Appwrite Cloud](https://cloud.appwrite.io/), followed by creating a new project and an API key with the scopes `users.read` and `users.write`.
|
||||
|
||||

|
||||
|
||||
> Note: If you plan to deploy this application publicly, please also add the hostname of your web app as a Web platform to the project.
|
||||
|
||||
### SvelteKit
|
||||
|
||||
To build this app, we will use SvelteKit, a framework that lets you build web applications using JavaScript. For the purpose of this blog, we will use a server function in the SvelteKit app to create our custom auth flow. However, you can also use an Appwrite function or develop your own backend API if you prefer that.
|
||||
|
||||
We will first set up a skeleton SvelteKit project (without TypeScript):
|
||||
|
||||
```bash
|
||||
npm create svelte@latest my-project
|
||||
cd my-project
|
||||
npm i
|
||||
```
|
||||
|
||||
Next, we shall create a `.env` file at the root of the directory and add the following:
|
||||
|
||||
```bash
|
||||
PUBLIC_APPWRITE_ENDPOINT=
|
||||
PUBLIC_APPWRITE_PROJECT_ID=
|
||||
APPWRITE_API_KEY=
|
||||
```
|
||||
|
||||
## Creating the server function
|
||||
|
||||
To create our server function, which contains the custom auth flow and creates a token, we will first install the Appwrite Node.js SDK by running the following command in our terminal:
|
||||
|
||||
```bash
|
||||
npm i node-appwrite
|
||||
```
|
||||
|
||||
We will then develop our API route `/auth` by creating a file `./src/routes/auth/+server.js` and add the following code:
|
||||
|
||||
```js
|
||||
import { Client, Users, ID, Query } from 'node-appwrite';
|
||||
import { PUBLIC_APPWRITE_ENDPOINT, PUBLIC_APPWRITE_PROJECT_ID } from '$env/static/public'; // Gets the public environment variables shared with the client
|
||||
import { env } from '$env/dynamic/private'; // Gets the private server-only environment variable
|
||||
|
||||
const endpoint = PUBLIC_APPWRITE_ENDPOINT;
|
||||
const projectId = PUBLIC_APPWRITE_PROJECT_ID;
|
||||
const apiKey = env.APPWRITE_API_KEY;
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint(endpoint)
|
||||
.setProject(projectId)
|
||||
.setKey(apiKey);
|
||||
|
||||
const users = new Users(client);
|
||||
|
||||
/**
|
||||
* Returns user if user exists in Appwrite, if not creates a new user
|
||||
*
|
||||
* @param {string} email
|
||||
* @returns {Promise<import("node-appwrite").Models.User>} user
|
||||
*/
|
||||
async function getUser(email) {
|
||||
try {
|
||||
let usersList = await users.list([ Query.equal('email', email) ]);
|
||||
if (usersList.total != 0) {
|
||||
return usersList.users[0];
|
||||
} else {
|
||||
return await users.create(ID.unique(), email);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Logic for authentication
|
||||
*
|
||||
* @param {string} email
|
||||
* @param {string} password
|
||||
* @returns {Promise<import("node-appwrite").Models.User>} user
|
||||
*/
|
||||
async function authLogic(email, password) {
|
||||
try {
|
||||
// You can have any auth logic here. For this example, we're only matching the password with '123456'
|
||||
if (password === '123456') {
|
||||
return await getUser(email);
|
||||
} else {
|
||||
returns null;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
export async function POST({ request }) {
|
||||
try {
|
||||
const requestBody = await request.json();
|
||||
const email = requestBody.email;
|
||||
const password = requestBody.password;
|
||||
|
||||
// Call the auth logic
|
||||
let user = await authLogic(email, password);
|
||||
|
||||
// If user exists, create a token
|
||||
if(user) {
|
||||
let token = await users.createToken(user.$id);
|
||||
|
||||
// Ideally, you should not send the token object in response. Send the token secret to the user through an alternative secure channel
|
||||
return new Response(JSON.stringify({ user, token }), { status: 200, headers: { 'Content-Type': 'application/json' } });
|
||||
} else {
|
||||
return new Response(JSON.stringify({ message: 'Invalid credentials' }), { status: 401, headers: { 'Content-Type': 'application/json' } });
|
||||
}
|
||||
} catch(err){
|
||||
console.error(err);
|
||||
return new Response(JSON.stringify({ message: err.message }), { status: 500, headers: { 'Content-Type': 'application/json' } });
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
When a `POST` request is sent to this endpoint, the `POST` action uses the `authLogic` function (which can contain any custom authentication logic). On successful credentials verification, the function returns a user from Appwrite (or creates a new one) using the `getUser` function.
|
||||
|
||||
One highly important note for production applications is that unless the client is already trusted, you should not return the token object directly to the client application. Instead, the token secret should be sent to the user over a secure channel such as email or SMS.
|
||||
|
||||
## Developing the client app
|
||||
|
||||
Before we create our client app functionality, we will set up the Appwrite Web SDK. We will first install the SDK by running the following command in our terminal:
|
||||
|
||||
```bash
|
||||
npm i appwrite
|
||||
```
|
||||
|
||||
We will then create a file `./src/lib/appwrite.js` and add the following code:
|
||||
|
||||
```js
|
||||
import { Client, Account } from 'appwrite';
|
||||
import { PUBLIC_APPWRITE_ENDPOINT, PUBLIC_APPWRITE_PROJECT_ID } from '$env/static/public';
|
||||
|
||||
const endpoint = PUBLIC_APPWRITE_ENDPOINT;
|
||||
const projectId = PUBLIC_APPWRITE_PROJECT_ID;
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint(endpoint) // Your API Endpoint
|
||||
.setProject(projectId); // Your project ID;
|
||||
|
||||
export const account = new Account(client);
|
||||
```
|
||||
|
||||
Next, we will develop a page at the index route of our demo app. As this is a demo app, the code will focus only on the application logic. All CSS or styling-related information will be accessible in the final project repository at the end of the blog.
|
||||
|
||||
We will create a file `./src/routes/+page.svelte` and add the following code:
|
||||
|
||||
```html
|
||||
<script>
|
||||
import { account } from '$lib/appwrite';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
let user = '';
|
||||
let session = '';
|
||||
let token = '';
|
||||
|
||||
let state = ['notLoggedIn', 'tokenGenerated', 'loggedIn'];
|
||||
let currentState = state[0];
|
||||
|
||||
async function createToken(event) {
|
||||
try {
|
||||
event.preventDefault();
|
||||
|
||||
let formData = new FormData(event.target);
|
||||
const email = formData.get('email');
|
||||
const password = formData.get('password');
|
||||
|
||||
let authRequest = await fetch('/auth', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ email, password })
|
||||
});
|
||||
|
||||
let authRequestBody = await authRequest.json();
|
||||
|
||||
user = authRequestBody.user;
|
||||
token = authRequestBody.token;
|
||||
currentState = state[1];
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
async function createSession() {
|
||||
session = await account.createSession(user.$id, token.secret);
|
||||
currentState = state[2];
|
||||
}
|
||||
|
||||
async function logout() {
|
||||
token = '';
|
||||
session = '';
|
||||
currentState = state[0];
|
||||
await account.deleteSession('current');
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
await logout();
|
||||
});
|
||||
</script>
|
||||
|
||||
<h1>Custom Token Auth Demo</h1>
|
||||
|
||||
{#if currentState == state[0]}
|
||||
<div>
|
||||
<h2>Login</h2>
|
||||
<form on:submit={createToken}>
|
||||
<div>
|
||||
<label for="email">Email</label>
|
||||
<input type="email" id="email" name="email" placeholder="Enter any email id" required />
|
||||
</div>
|
||||
<div>
|
||||
<label for="password">Password (Enter code: 123456)</label>
|
||||
<input type="text" id="password" name="password" placeholder="123456" required />
|
||||
</div>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
</div>
|
||||
{:else if currentState == state[1]}
|
||||
<div>
|
||||
<h2>Token secret: {token.secret}</h2>
|
||||
<button on:click={createSession}>Generate session</button>
|
||||
</div>
|
||||
{:else if currentState == state[2]}
|
||||
<div>
|
||||
<h2>Session details</h2>
|
||||
<pre>{JSON.stringify(session, undefined, 4)}</pre>
|
||||
<button type="submit" on:click={logout}>Logout</button>
|
||||
</div>
|
||||
{/if}
|
||||
```
|
||||
|
||||
The page has a `currentState` property, which helps track whether a user has yet to start the auth flow (`state[0]`), has received the token secret (`state[1]`), and has an active session (`state[2]`). In `state[0]`, the user submits their email and password (hardcoded to `123456` for the demo), which are then sent to our server function. In `state[1]`, the user can generate a session using the token secret and user ID received from our server function. In `state[2]`, the user can see the current session object, thus showcasing a successful login.
|
||||
|
||||
## Testing the project
|
||||
|
||||
Once we have complete the steps above, the project is ready to test. Run the following command in the terminal:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
# Next steps
|
||||
|
||||
And with that, our demo project to try custom token authentication in Appwrite is ready! You can find the application’s complete source code at this [GitHub Repo](https://github.com/appwrite-community/appwrite-custom-token-auth-demo).
|
||||
|
||||
Additionally, if you would like to learn more about Appwrite Auth, here are some resources:
|
||||
|
||||
- [Appwrite Auth docs](https://appwrite.io/docs/products/auth): These documents provide more information on how to use Appwrite Auth.
|
||||
- [Appwrite Discord](https://discord.com/invite/appwrite): Connect with other developers and the Appwrite team for discussion, questions, and collaboration.
|
||||
@@ -168,7 +168,7 @@ export default async ({ req, res, log, error }) => {
|
||||
port: 14714
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
await client.connect();
|
||||
}
|
||||
|
||||
@@ -279,7 +279,7 @@ You can look at the entire example put together in the [query Neo4j AuraDB](http
|
||||
|
||||
Upstash is a data platform that offers services such as Redis, Kafka, or QStash, but most importantly, a vector database. Vector database stores multi-dimensional numeric representations of your data (embeddings) in an index, allowing you to find similarities between them quickly.
|
||||
|
||||
There are AI models to generate embeddings from text, music, or images, which is the main purpose of vector databases. Using a AI model such as a large language model (LLM), you could create a vector database of your product names. Later, a visitor may be looking for a flower pot, but thanks to the vector database, your website can now recommend watering cans and fertilizer.
|
||||
There are AI models to generate embeddings from text, music, or images, which is the main purpose of vector databases. Using a AI model such as a large language model (LLM), you could create a vector database of your product names. Later, a visitor may be looking for a flower pot, but thanks to the vector database, your website can now recommend watering cans and fertilizer.
|
||||
|
||||
Integrating with Upstash Vector is unbelievably simple. Usually, you would have to connect to an AI model yourself to generate embeddings. In latest Upstash, you can pick model when creating an index, and the embedding is created for you automatically, for any input you provide. With that in mind, you can create an Appwrite Function that connects to Upstash, and inserts your data.
|
||||
|
||||
@@ -335,6 +335,6 @@ If needed for your use-case, you can disable automatic embedding generation from
|
||||
|
||||
Your database journey doesn’t end here. There are other databases you might already love, or look forward to trying in your next project. Thanks to nature of Appwrite Functions, your imagination is the limit. We look forward showcasing more databases and how you can integrate them with Appwrite.
|
||||
|
||||
If you want to share your favorite database with us, or need help integrating with your database, I invite you to [Join our Discord](http://appwrite.io/discord) community.
|
||||
If you want to share your favorite database with us, or need help integrating with your database, I invite you to [Join our Discord](https://appwrite.io/discord) community.
|
||||
|
||||
Lastly, if you are feeling inspired, you can contribute to templates you have read about. In our [Appwrite Functions templates](https://github.com/appwrite/templates) repository, we implemented integrations in Node.JS, but developers use a dozen other languages. We would love to see issues and pull requests converting the function into other languages.
|
||||
@@ -17,7 +17,7 @@ If you’re a mobile developer who doesn’t (want to) use Flutter, we have grea
|
||||
|
||||
## Appwrite and React Native
|
||||
|
||||
The addition of the SDK to Appwrite is great news for React Native mobile developers. Appwrite's commitment to providing a secure, scalable backend, combined with React Native's efficiency and native capabilities, creates a strong toolkit for building mobile applications. This integration means developers can now enjoy the best of both worlds: Appwrite's [ready-to-use APIs](https://appwrite.io/docs/references) for Authentication, Database, Storage, Messaging, Realtime, and more, alongside React Native's seamless developer experience and native feel.
|
||||
The addition of the SDK to Appwrite is great news for React Native mobile developers. Appwrite's commitment to providing a secure, scalable backend, combined with React Native's efficiency and native capabilities, creates a strong toolkit for building mobile applications. This integration means developers can now enjoy the best of both worlds: Appwrite's [ready-to-use APIs](/docs/references) for Authentication, Database, Storage, Messaging, Realtime, and more, alongside React Native's seamless developer experience and native feel.
|
||||
|
||||
Appwrite already has a Web SDK, so why a dedicated React Native SDK? React Native requires abstractions of device and system APIs to access device permissions, cameras, storage, gyroscope, and more. Appwrite leverages [Expo](https://docs.expo.dev/) to implement APIs such as Appwrite Storage that require access to device and system APIs.
|
||||
|
||||
@@ -27,7 +27,7 @@ As the SDK is released in open beta, we will be working with the React Native co
|
||||
|
||||
## Building mobile apps
|
||||
|
||||
What can you build with Appwrite and React Native? Basically, anything you can think of from social media platforms and e-commerce apps to productivity tools and interactive games. Appwrite even supports push notifications for your mobile app with [Messaging](https://appwrite.io/docs/products/messaging/send-push-notifications).
|
||||
What can you build with Appwrite and React Native? Basically, anything you can think of from social media platforms and e-commerce apps to productivity tools and interactive games. Appwrite even supports push notifications for your mobile app with [Messaging](/docs/products/messaging/send-push-notifications).
|
||||
|
||||
We’ve created a playground on [GitHub](https://github.com/appwrite/playground-for-react-native) where we will add simple ideas for getting started with Appwrite and React Native. You can also find inspiration from other Appwrite projects on [builtwithappwrite.io](http://builtwithappwrite.io) to see how other mobile developers have used Appwrite as their backend.
|
||||
|
||||
@@ -39,7 +39,7 @@ Diving into Appwrite's React Native SDK is easy. Here's how to get started:
|
||||
|
||||
### Step 1: Set up Appwrite
|
||||
|
||||
First thing first, you must set up an Appwrite project. To do so, you must either [create an Appwrite Cloud account](https://cloud.appwrite.io) or [self-host Appwrite](https://appwrite.io/docs/advanced/self-hosting) on your system.
|
||||
First thing first, you must set up an Appwrite project. To do so, you must either [create an Appwrite Cloud account](https://cloud.appwrite.io) or [self-host Appwrite](/docs/advanced/self-hosting) on your system.
|
||||
|
||||

|
||||
|
||||
@@ -58,7 +58,7 @@ npx expo install react-native-appwrite react-native-url-polyfill
|
||||
|
||||
### Step 3: Explore the Documentation
|
||||
|
||||
Familiarize yourself with [Appwrite's documentation](https://appwrite.io/docs). It's packed with tutorials, examples, and API references designed to get you up to speed in no time.
|
||||
Familiarize yourself with [Appwrite's documentation](/docs). It's packed with tutorials, examples, and API references designed to get you up to speed in no time.
|
||||
|
||||
### Step 4: Start Building
|
||||
|
||||
@@ -73,7 +73,7 @@ client
|
||||
.setEndpoint('http://cloud.appwrite.io/v1') // Your Appwrite Endpoint
|
||||
.setProject('455x34dfkj') // Your project ID
|
||||
.setPlatform('com.example.myappwriteapp'); // Your application ID or bundle ID
|
||||
|
||||
|
||||
const account = new Account(client);
|
||||
|
||||
// Register a user
|
||||
@@ -85,14 +85,14 @@ account.create(ID.unique(), 'me@example.com', 'password', 'Jane Doe')
|
||||
});
|
||||
```
|
||||
|
||||
Read the [quick start](http://appwrite.io/docs/quick-starts/react-native) to get started or find a [tutorial](http://appwrite.io/docs/tutorials/react-native/step-1) to build an ideas tracker with React Native.
|
||||
Read the [quick start](/docs/quick-starts/react-native) to get started or find a [tutorial](/docs/tutorials/react-native/step-1) to build an ideas tracker with React Native.
|
||||
|
||||
## Resources
|
||||
|
||||
Visit our documentation to learn more about our SDKs, join us on Discord to be part of the discussion, view our blog and YouTube channel, or visit our GitHub repository to see our source code.
|
||||
|
||||
- [Docs](https://appwrite.io/docs/sdks)
|
||||
- [Docs](/docs/sdks)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
- [GitHub](https://github.com/appwrite/appwrite)
|
||||
|
||||
@@ -9,7 +9,7 @@ author: jake-barnby
|
||||
category: product
|
||||
featured: false
|
||||
---
|
||||
We are excited to announce a significant enhancement to the development experience across all Appwrite client and server-side SDKs, Enums SDK Support.
|
||||
We are excited to announce a significant enhancement to the development experience across all Appwrite client and server-side SDKs, Enums SDK Support.
|
||||
|
||||
This enhancement is designed to streamline the development process, improve code quality, and facilitate seamless integration with Appwrite's backend services.
|
||||
|
||||
@@ -19,7 +19,7 @@ Enums, or enumerations, are a powerful programming construct that enables develo
|
||||
|
||||
# Introducing Enum SDK support in Appwrite
|
||||
|
||||
Currently, when you want to use an endpoint with a predefined set of allowed values, you must look up the exact value in the documentation. This can be time-consuming and error-prone.
|
||||
Currently, when you want to use an endpoint with a predefined set of allowed values, you must look up the exact value in the documentation. This can be time-consuming and error-prone.
|
||||
|
||||
This new feature, however, ensures you can use more readable and self-documenting code instead of having to remember and type out raw values.
|
||||
|
||||
@@ -37,15 +37,15 @@ const account = new Account(client);
|
||||
account.createOAuth2Session(OAuthProvider.Apple, '[LINK_ON_SUCCESS]', '[LINK_ON_FAILURE]', true);
|
||||
```
|
||||
|
||||
This new feature will improve the experience of building with Appwrite and lower the barrier for new developers to start. As always, we aim to make life easier, not harder, and we look forward to your feedback.
|
||||
This new feature will improve the experience of building with Appwrite and lower the barrier for new developers to start. As always, we aim to make life easier, not harder, and we look forward to your feedback.
|
||||
|
||||
# Resources
|
||||
|
||||
Visit our documentation to learn more about Enums SDK support, join us on Discord to be part of the discussion, view our blog and YouTube channel, or visit our GitHub repository to see our source code.
|
||||
|
||||
- [Docs](https://appwrite.io/docs/sdks#enums)
|
||||
- [Docs](/docs/sdks#enums)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
- [GitHub](https://github.com/appwrite/appwrite)
|
||||
|
||||
|
||||
@@ -68,9 +68,9 @@ With these new database improvements you have more possibilities for data retrie
|
||||
|
||||
Visit our documentation to learn more about Database operators, join us on Discord to be part of the discussion, view our blog and YouTube channel, or visit our GitHub repository to see our open-source code.
|
||||
|
||||
- [Docs](https://appwrite.io/docs/products/databases/queries)
|
||||
- [Docs](/docs/products/databases/queries)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
- [GitHub](https://github.com/appwrite/appwrite)
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ The problem we faced was that there was no way to access a session secret when u
|
||||
|
||||
# Getting started with SSR
|
||||
|
||||
As you get started with SSR it’s important to note that all methods we will be working with are based on Appwrite’s server SDKs. In the examples below, we will use the [Node JS SDK.](https://appwrite.io/docs/sdks#server)
|
||||
As you get started with SSR it’s important to note that all methods we will be working with are based on Appwrite’s server SDKs. In the examples below, we will use the [Node JS SDK.](/docs/sdks#server)
|
||||
|
||||
It’s also recommended that as you follow along with this article, you do not install any client SDK’s as that may lead to confusion. All examples use `node-appwrite`.
|
||||
|
||||
@@ -72,12 +72,12 @@ With the new authentication patterns for SSR, you’ll need to create two differ
|
||||
The admin client will need to be initialized with an API key in order to bypass rate limits when performing unauthenticated request or when we need to perform actions that bypass permissions. Without an API key our server will be rate limited when trying to make request to certain endpoints.
|
||||
|
||||
```jsx
|
||||
import { Client } from "node-appwrite"
|
||||
import { Client } from "node-appwrite"
|
||||
|
||||
const adminClient = new Client()
|
||||
.setEndpoint('https://cloud.appwrite.io/v1')
|
||||
.setProject('<YOUR_PROJECT_ID>')
|
||||
.setKey('<YOUR_API_KEY>')
|
||||
.setEndpoint('https://cloud.appwrite.io/v1')
|
||||
.setProject('<YOUR_PROJECT_ID>')
|
||||
.setKey('<YOUR_API_KEY>')
|
||||
```
|
||||
|
||||
### Session Client
|
||||
@@ -86,14 +86,14 @@ A session client will allow us to make requests as an authenticated end-user wit
|
||||
|
||||
```jsx
|
||||
const sessionClient = new Client()
|
||||
.setEndpoint('https://cloud.appwrite.io/v1')
|
||||
.setProject('<YOUR_PROJECT_ID>')
|
||||
.setEndpoint('https://cloud.appwrite.io/v1')
|
||||
.setProject('<YOUR_PROJECT_ID>')
|
||||
|
||||
const session = req.cookies.session
|
||||
const session = req.cookies.session
|
||||
|
||||
if (session) {
|
||||
sessionClient.setSession(session)
|
||||
}
|
||||
}
|
||||
|
||||
const user = await account.get()
|
||||
```
|
||||
@@ -160,7 +160,7 @@ export async function POST(request){
|
||||
|
||||
const { email, password } = await request.json()
|
||||
const session = await account.createEmailPasswordSession(email, password)
|
||||
|
||||
|
||||
cookies().set('session', session.secret, {
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
@@ -196,12 +196,12 @@ export async function GET(request){
|
||||
|
||||
Visit our documentation to learn more about SSR, join us on Discord to be part of the discussion, visit our blog and YouTube channel to learn more, or visit our GitHub repository to see our source code.
|
||||
|
||||
- [Docs](https://appwrite.io/docs/products/auth/server-side-rendering)
|
||||
- [Docs](/docs/products/auth/server-side-rendering)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
- [GitHub repository](https://github.com/appwrite/appwrite)
|
||||
|
||||
SSR will be available as part of the Appwrite 1.5 release on [GitHub](https://github.com/appwrite/appwrite) and [Cloud](https://cloud.appwrite.io/register) in March 2024.
|
||||
|
||||
[Go back to Init](http://appwrite.io/init)
|
||||
[Go back to Init](/init)
|
||||
|
||||
@@ -8,7 +8,7 @@ timeToRead: 10
|
||||
author: vincent-ge
|
||||
category: migration
|
||||
---
|
||||
If you’re ready to move from Firebase to Appwrite, or you just want to explore your BaaS options, we can give you a jump start with Appwrite Migrations.
|
||||
If you’re ready to move from Firebase to Appwrite, or you just want to explore your BaaS options, we can give you a jump start with Appwrite Migrations.
|
||||
|
||||

|
||||
|
||||
@@ -45,7 +45,7 @@ Migrations will run in the background, get a cup of tea or coffee, and return in
|
||||
|
||||
## Wrapping up the move
|
||||
|
||||
After your migration is completed, you’ll need to do a few more things to wrap up your move to Appwrite.
|
||||
After your migration is completed, you’ll need to do a few more things to wrap up your move to Appwrite.
|
||||
|
||||
First, you register your existing web, mobile, and native apps as platforms. Follow one of these [quick starts](/docs/quick-starts) to learn how.
|
||||
|
||||
@@ -55,4 +55,4 @@ Finally, learn about [Appwrite Functions](/docs/products/functions/quick-start)
|
||||
|
||||
## Join the discussion
|
||||
|
||||
We’re always having a blast on [Discord](/discord). With members in the community from all over the world, you’ll always find someone to support and share your Appwrite journey.
|
||||
We’re always having a blast on [Discord](https://appwrite.io/discord). With members in the community from all over the world, you’ll always find someone to support and share your Appwrite journey.
|
||||
@@ -9,13 +9,13 @@ author: aditya-oberai
|
||||
category: product
|
||||
---
|
||||
|
||||
If you are looking to build a mobile app, website, tool, or any other application that needs a backend, then you also know the daunting tasks that await. This is probably what brought you to this blog in the first place: looking for a solution to take care of your backend. BaaS provides pre-built backend infrastructure and services to simplify app development, handling server-side tasks like data storage, user management, APIs, server maintenance, security, database management, and more. Two of these services are Firebase and Appwrite.
|
||||
If you are looking to build a mobile app, website, tool, or any other application that needs a backend, then you also know the daunting tasks that await. This is probably what brought you to this blog in the first place: looking for a solution to take care of your backend. BaaS provides pre-built backend infrastructure and services to simplify app development, handling server-side tasks like data storage, user management, APIs, server maintenance, security, database management, and more. Two of these services are Firebase and Appwrite.
|
||||
|
||||
Appwrite and Firebase are both solid options to choose as the Backend-as-a-Service (BaaS) for your app. However, their feature sets can vary substantially. In this article, we will give you a rundown of Appwrite and Firebase to understand how each provider will fit your specific needs.
|
||||
|
||||
# Appwrite - Open-source backend platform
|
||||
|
||||
In 2019, [Appwrite](https://appwrite.io/) started as an open-source project to make software development more accessible and enjoyable. It is a Backend as a Service platform with a vibrant developer community. You can self-host Appwrite on your server or utilize [Appwrite Cloud](https://cloud.appwrite.io/). Appwrite provides many features, including user authentication, databases, storage, real-time features, and functions. It is known for its flexibility, security, and extensibility, enabling you to customize backend logic and build applications tailored to your needs. You can view Appwrite’s source code on [GitHub](https://github.com/appwrite/appwrite).
|
||||
In 2019, [Appwrite](/) started as an open-source project to make software development more accessible and enjoyable. It is a Backend as a Service platform with a vibrant developer community. You can self-host Appwrite on your server or utilize [Appwrite Cloud](https://cloud.appwrite.io/). Appwrite provides many features, including user authentication, databases, storage, real-time features, and functions. It is known for its flexibility, security, and extensibility, enabling you to customize backend logic and build applications tailored to your needs. You can view Appwrite’s source code on [GitHub](https://github.com/appwrite/appwrite).
|
||||
|
||||
# Firebase - Google-owned BaaS
|
||||
|
||||
@@ -38,7 +38,7 @@ Authentication is the process of verifying a user's identity. This is typically
|
||||
|
||||
*Differences:*
|
||||
|
||||
- Appwrite's authentication system allows developers to integrate with any existing external authentication systems through [custom token login](https://appwrite.io/docs/products/auth/custom-token), which allows for various new use cases such as passkey authentication. It also allows for password [history](https://appwrite.io/docs/products/auth/security#password-history) and [dictionary](https://appwrite.io/docs/products/auth/security#password-dictionary), [session limits](https://appwrite.io/docs/products/auth/security#session-limits), and [personal data](https://appwrite.io/docs/products/auth/security#personal-data) checks on your passwords.
|
||||
- Appwrite's authentication system allows developers to integrate with any existing external authentication systems through [custom token login](/docs/products/auth/custom-token), which allows for various new use cases such as passkey authentication. It also allows for password [history](/docs/products/auth/security#password-history) and [dictionary](/docs/products/auth/security#password-dictionary), [session limits](/docs/products/auth/security#session-limits), and [personal data](/docs/products/auth/security#personal-data) checks on your passwords.
|
||||
- Firebase offers a user-friendly authentication system that seamlessly integrates with other Firebase services, providing developers with a streamlined experience.
|
||||
|
||||
## Database
|
||||
@@ -54,7 +54,7 @@ Both Appwrite and Firebase provide databases that can be used depending on the n
|
||||
|
||||
*Differences:*
|
||||
|
||||
- Appwrite's database offers an abstraction layer on top of MariaDB, allowing developers to develop custom schema and use queries without any pre-existing SQL knowledge. Also, you can [configure permissions](https://appwrite.io/docs/advanced/platform/permissions#appwrite-resource) in Appwrite within the Console, making this an easy task.
|
||||
- Appwrite's database offers an abstraction layer on top of MariaDB, allowing developers to develop custom schema and use queries without any pre-existing SQL knowledge. Also, you can [configure permissions](/docs/advanced/platform/permissions#appwrite-resource) in Appwrite within the Console, making this an easy task.
|
||||
- Firebase provides a NoSQL, document-oriented database called Cloud Firestore for storing and managing data in a non-relational manner. To manage permissions, they offer a different product called Security Rules, which allows more flexibility but increases the learning curve.
|
||||
|
||||
## Storage
|
||||
@@ -70,7 +70,7 @@ Storage allows you to manage files in your project. It can store images, videos,
|
||||
*Differences:*
|
||||
|
||||
- Firebase's storage system is a direct extension of Google Cloud Storage and has additional out-of-the-box integrations such as image filtering and video transcoding.
|
||||
- Appwrite Storage offers a dedicated API for [image transformations](https://appwrite.io/docs/products/storage/images), including functionalities such as manipulating resolution, image reformatting, caching, and compression.
|
||||
- Appwrite Storage offers a dedicated API for [image transformations](/docs/products/storage/images), including functionalities such as manipulating resolution, image reformatting, caching, and compression.
|
||||
- Appwrite Storage offers file encryption for increased security as well as gzip and zstd compression for network transfer optimization.
|
||||
|
||||
## Functions
|
||||
@@ -87,8 +87,8 @@ Functions are "self-contained" modules of code that accomplish a specific task.
|
||||
|
||||
*Differences:*
|
||||
|
||||
- Appwrite offers easy and quick deployment of [functions using Git](https://appwrite.io/docs/products/functions/deploy-from-git), has ready-to-use templates, and supports a large number of runtimes.
|
||||
- Appwrite supports [function runtimes across over 10 different languages](https://appwrite.io/docs/products/functions/runtimes), including Dart, Bun, Kotlin, and Swift, whereas Firebase only supports JavaScript, TypeScript, and Python.
|
||||
- Appwrite offers easy and quick deployment of [functions using Git](/docs/products/functions/deploy-from-git), has ready-to-use templates, and supports a large number of runtimes.
|
||||
- Appwrite supports [function runtimes across over 10 different languages](/docs/products/functions/runtimes), including Dart, Bun, Kotlin, and Swift, whereas Firebase only supports JavaScript, TypeScript, and Python.
|
||||
- Firebase offers additional event triggers for different Google Cloud services.
|
||||
|
||||
## Realtime
|
||||
@@ -126,21 +126,21 @@ While both Appwrite and Firebase are great Backend-as-a-Service offerings that s
|
||||
|
||||
Here’s a table that compares both Appwrite and Firebase:
|
||||
|
||||
| Feature | Appwrite | Firebase |
|
||||
| --- | --- | --- |
|
||||
| Deployment | Self-hosted or cloud-hosted | Cloud-hosted only |
|
||||
| Free plan | Yes, Starter plan | Yes, Spark plan |
|
||||
| Paid plan | Yes, Pro plan - $15 per month per member and addons | Yes, Blaze plan - Pay-as-you-go |
|
||||
| Open source | Yes | No |
|
||||
| Support | Community and email | Community, Support Portal, and help center |
|
||||
| Functions marketplace | Has a marketplace featuring a variety of function templates and integrations such as Discord bots, payments with Stripe, ChatGPT API, etc. | Has an extensions hub featuring pre-built functions ready to deploy. |
|
||||
| Messaging providers | 10 providers covering SMS, email, and push notifications | No external providers, but offers the infrastructure for FCM and In-App Messaging |
|
||||
| Feature | Appwrite | Firebase |
|
||||
| ------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| Deployment | Self-hosted or cloud-hosted | Cloud-hosted only |
|
||||
| Free plan | Yes, Free plan | Yes, Spark plan |
|
||||
| Paid plan | Yes, Pro plan - $15 per month per member and addons | Yes, Blaze plan - Pay-as-you-go |
|
||||
| Open source | Yes | No |
|
||||
| Support | Community and email | Community, Support Portal, and help center |
|
||||
| Functions marketplace | Has a marketplace featuring a variety of function templates and integrations such as Discord bots, payments with Stripe, ChatGPT API, etc. | Has an extensions hub featuring pre-built functions ready to deploy. |
|
||||
| Messaging providers | 10 providers covering SMS, email, and push notifications | No external providers, but offers the infrastructure for FCM and In-App Messaging |
|
||||
|
||||
# Resources
|
||||
|
||||
If you want to learn more about Appwrite, you can find more resources below.
|
||||
|
||||
- [Appwrite documentation](https://appwrite.io/docs) - Visit Appwrite’s docs to learn how to get started and more about Appwrite’s functionality.
|
||||
- [Appwrite documentation](/docs) - Visit Appwrite’s docs to learn how to get started and more about Appwrite’s functionality.
|
||||
- [Appwrite GitHub repository](https://github.com/appwrite/appwrite/stargazers)Explore the code and architecture and see how you can contribute to Appwrite.
|
||||
- [Appwrite Discord](https://appwrite.io/discord) - Join Appwrite’s Discord server, be part of a vibrant community, and get support.
|
||||
- [Appwrite YouTube](https://www.youtube.com/@Appwrite)
|
||||
- [Appwrite YouTube](https://www.youtube.com/@Appwrite)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
layout: post
|
||||
title: Demystifying password hashing algorithms
|
||||
description: What are password hashing algorithms and how they help secure user credentials in your application.
|
||||
title: How password hashing algorithms keep your data safe
|
||||
description: Learn about password hashing algorithms and how they help secure user credentials in your application.
|
||||
date: 2023-10-20
|
||||
cover: /images/blog/password-hashing-algorithms.png
|
||||
timeToRead: 7
|
||||
@@ -9,13 +9,15 @@ author: aditya-oberai
|
||||
category: authentication, security
|
||||
---
|
||||
|
||||
In today's digital world, securing sensitive information such as passwords is of paramount importance. Password hashing algorithms play a crucial role in protecting user credentials and ensuring the integrity of authentication systems. In this blog, we will delve into the intricacies of password hashing algorithms, explore their key characteristics, and discuss some of the most widely used and secure algorithms to help you make informed decisions when implementing password storage and verification in your applications.
|
||||
In today's digital world, keeping sensitive information like passwords secure is extremely important. Password hashing algorithms are essential for protecting user credentials and ensuring authentication systems are reliable.
|
||||
|
||||
In this blog, we'll break down how password hashing algorithms work, highlight their key features, and review some of the most popular and secure algorithms. This will help you make informed choices when setting up password storage and verification in your applications.
|
||||
|
||||
## What is a password hashing algorithm?
|
||||
|
||||
**Password hashing algorithms** are specialized mathematical functions that transform plaintext passwords into unique, fixed-size outputs, known as hashes, which are then stored in databases. Through the use of techniques such as salting, adjustable work factors, and memory hardness, modern password hashing algorithms are designed to thwart attacks and keep user data secure.
|
||||
**Password hashing algorithms** are specialized mathematical functions that transform plain text passwords into unique, fixed-size outputs, known as hashes, which are then stored in databases. Through the use of techniques such as salting, adjustable work factors, and memory hardness, modern password hashing algorithms are designed to prevent attacks like rainbow tables and data breaches.
|
||||
|
||||
The mathematical process of password hashing involves applying a hash function to a combination of a password and a salt, iterating the process based on a work factor, and, in some cases, incorporating memory hardness to increase the computational complexity.
|
||||
Password hashing involves using a hash function to combine a password with a unique value called a salt. This process is repeated multiple times based on a set difficulty level. Sometimes, additional memory usage is included to make the process even more complex and secure.
|
||||
|
||||
This function would operate as follows:
|
||||
|
||||
@@ -34,7 +36,7 @@ The result is a fixed-size hash that is unique, deterministic, and resistant to
|
||||
Password hashing algorithms have certain characteristics:
|
||||
|
||||
- **One-way function**
|
||||
Password hashing algorithms should be one-way functions, making it computationally infeasible to reverse-engineer the original password from the hash output, preventing attackers from trying to retrieve user passwords from the stored hashes.
|
||||
Password hashing algorithms should be one-way functions, so it's nearly impossible to reverse-engineer the original password from the hash. This prevents attackers from getting user passwords from stored hashes.
|
||||
- **Deterministic**
|
||||
A password hashing algorithm must always produce the same hash output for a given input to ensure consistency and reliability.
|
||||
- **Fixed-size output**
|
||||
@@ -42,13 +44,13 @@ Password hashing algorithms must produce a fixed-size output (hash) regardless o
|
||||
- **Slow computation**
|
||||
Unlike general hashing algorithms, which prioritize fast computation, password hashing algorithms should be intentionally slow to compute. This characteristic makes it more time-consuming and resource-intensive for attackers to perform brute-force attacks or attempt to guess passwords using a large number of inputs.
|
||||
- **Avalanche effect**
|
||||
A small change in the input should result in a significant change in the hash output, making the new output appear uncorrelated with the old output. This property makes it difficult for attackers to predict the input based on the output or find two different inputs that produce the same output (collision). For example, the SHA-256 hash for `eight` is `c195d2d8756234367242ba7616c5c60369bc25ced2dcb5b92808d31b58ef217a`, but for `right` is `27042f4e6eca7d0b2a7ee4026df2ecfa51d3339e6d122aa099118ecd8563bad9`, despite having only one character different.
|
||||
A small change in the input should cause a big change in the hash output, making the new output look unrelated to the old one. This makes it hard for attackers to guess the input from the output or find two inputs that create the same hash (collision). For example, the SHA-256 hash for `eight` is `c195d2d8756234367242ba7616c5c60369bc25ced2dcb5b92808d31b58ef217a`, but for `right` is `27042f4e6eca7d0b2a7ee4026df2ecfa51d3339e6d122aa099118ecd8563bad9`, despite having only one different character.
|
||||
- **Pseudorandomness**
|
||||
The output of a password hashing algorithm should appear random and uniformly distributed, making it difficult for attackers to predict patterns or relationships between inputs and their corresponding hash outputs.
|
||||
The output of a password hashing algorithm should look random and evenly spread out, so attackers can't find patterns or guess relationships between the inputs and their hash outputs.
|
||||
- **Resistance to side-channel attacks**
|
||||
Password hashing algorithms should be designed to resist side-channel attacks, such as timing attacks, where an attacker attempts to gain information about the password or hash by analyzing the time taken to compute the hash.
|
||||
Password hashing algorithms should be designed to resist side-channel attacks. An example of this would timing attacks, where an attacker attempts to gain information about the password or hash by analyzing the time taken to compute the hash.
|
||||
- **Adjustable work factor**
|
||||
A good password hashing algorithm should allow for an adjustable work factor, also known as a cost factor or iteration count. This increases the algorithm's computational complexity over time as hardware capabilities improve, ensuring that the password hashing process remains secure and resource-intensive for attackers.
|
||||
A good password hashing algorithm should let you adjust the work factor, which means increasing the complexity over time as hardware gets better. This keeps the password hashing process secure and too resource-intensive for dictionary attacks.
|
||||
- **Memory hardness**
|
||||
Some modern password hashing algorithms are designed to be memory-hard, meaning that they require a significant amount of memory to compute the hash. This characteristic makes it more difficult for attackers to perform parallel attacks using specialized hardware, such as GPUs or ASICs, which have limited memory resources.
|
||||
- **Wide adoption and peer review**
|
||||
|
||||
@@ -14,7 +14,7 @@ With digital security taking more and more importance in our day-to-day lives, r
|
||||
|
||||
# Understanding 2FA
|
||||
|
||||
2FA adds an extra layer of security to the traditional login process by requiring users to provide two different types of information before gaining access to an account. This method significantly enhances security by combining something the user knows (like a password) with something the user has (such as a mobile device for receiving SMS codes or an authenticator app) or is (biometrics, for example).
|
||||
2FA adds an extra layer of security to the traditional login process by requiring users to provide two different types of information before gaining access to an account. This method significantly enhances security by combining something the user knows (like a password) with something the user has (such as a mobile device for receiving SMS codes or an authenticator app) or is (biometrics, for example).
|
||||
|
||||
The vulnerabilities of single-factor authentication, primarily consisting of password-only systems, lie in their susceptibility to phishing, social engineering, and brute force attacks. 2FA addresses these vulnerabilities by making unauthorized access considerably more challenging for attackers.
|
||||
|
||||
@@ -66,7 +66,7 @@ Effective implementation of 2FA enhances security measures for applications, pro
|
||||
|
||||
# Implementing 2FA in your apps with Appwrite
|
||||
|
||||
With the release of Appwrite 1.5, we have introduced the ability to implement [2FA](https://appwrite.io/docs/products/auth/2fa) via Appwrite Authentication. Currently, we offer three methods for implementing the second factor:
|
||||
With the release of Appwrite 1.5, we have introduced the ability to implement [2FA](/docs/products/auth/mfa) via Appwrite Authentication. Currently, we offer three methods for implementing the second factor:
|
||||
|
||||
- **Authenticator Apps (TOTP):** Use common authenticator apps like Google Authenticator or Twilio Authy for authentication.
|
||||
- **Emails:** A verified email can be used for authentication, providing a 6-digit code to the user.
|
||||
@@ -76,8 +76,8 @@ With the release of Appwrite 1.5, we have introduced the ability to implement [2
|
||||
|
||||
Visit our documentation to learn more about Appwrite, join us on Discord to be part of the discussion, view our blog and YouTube channel, or visit our GitHub repository to see our source code.
|
||||
|
||||
- [Docs](https://appwrite.io/docs/products/auth/2fa)
|
||||
- [Docs](/docs/products/auth/mfa)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
- [GitHub](https://github.com/appwrite/appwrite)
|
||||
|
||||
@@ -9,32 +9,32 @@ author: aditya-oberai
|
||||
category: authentication, security
|
||||
---
|
||||
|
||||
Today, our lives are more digitally connected than ever. The internet has brought us a plethora of benefits, making day-to-day activities, such as shopping, banking, and communication, easier for society. This convenience does come at a cost, however. Every important activity we perform on the internet is associated with a digital identity, and this identity is only as secure as we make it.
|
||||
Today, we're more connected online than ever before. The internet has made things like shopping, banking, and communicating much easier. This convenience does come at a cost, however. Every important activity we perform on the internet is associated with a digital identity, and this identity is only as secure as we make it.
|
||||
|
||||
Unfortunately, as seen across multiple incidents in recent history, not everyone’s digital identity on the internet has been maintained securely. The primary culprit in these incidents, such as the [LinkedIn Data Breach](https://www.cbsnews.com/news/linkedin-2012-data-breach-hack-much-worse-than-we-thought-passwords-emails/) in 2012, the [Yahoo Data Breach](https://www.nytimes.com/2017/10/03/technology/yahoo-hack-3-billion-users.html) in 2012-13, or the [GoDaddy Data Breach](https://techcrunch.com/2021/11/22/godaddy-breach-million-accounts/) in 2021, is weak passwords.
|
||||
|
||||
As software developers, it is essential to remember that our applications’ data is only as secure as the people who use them. Identity verification carries the utmost importance here, which leads us to discuss the necessity of using passwords to secure access to data and resources in our software, or as we say in short, “password protection.” In this blog, let’s learn why strong password protection is essential and what best practices we can keep in mind while implementing the same.
|
||||
As software developers, it is essential to remember that our applications’ data is only as secure as the people who use them. Identity verification is crucial, which brings us to the importance of using passwords to keep data and resources safe in our software, or as we call it, "password protection." In this blog, let’s learn why strong password protection is essential and what best practices we can keep in mind while implementing the same.
|
||||
|
||||
## Why strong password protection is necessary to implement
|
||||
|
||||
There are numerous reasons why we as developers must implement password protection in our software:
|
||||
There are many reasons why we as developers must implement password protection in our software:
|
||||
|
||||
- **Safeguard User Data**
|
||||
Developers are responsible for protecting sensitive user information such as personal data, financial details, and other private information. Proper password protection ensures unauthorized individuals cannot access this data, helping maintain user trust and privacy.
|
||||
- **Safeguard user data.**
|
||||
Developers must protect sensitive user information like personal data and financial details. Proper password protection keeps unauthorized people from accessing their online accounts, helping maintain user trust and privacy.
|
||||
|
||||
- **Protect Application Integrity**
|
||||
Weak password protection can lead to unauthorized access, resulting in data breaches, application functionality tampering, and other malicious activities. By implementing robust password protection measures, developers can maintain the integrity of their applications and minimize the risk of cyberattacks.
|
||||
- **Protect application integrity.**
|
||||
Weak password protection can lead to unauthorized access, resulting in data and security breaches, application functionality tampering, and other malicious activities. By implementing good password protection and password management, developers can maintain the integrity of their applications and minimize the risk of cyberattacks.
|
||||
|
||||
- **Prevent Unauthorized Access**
|
||||
A strong password protection system helps prevent unauthorized users from gaining access to restricted areas of an application, such as admin panels or user accounts. This ensures that only authorized users can access and modify data, reducing the chances of data leaks and minimizing possible attack vectors.
|
||||
- **Prevent unauthorized access.**
|
||||
A strong password protection system stops unauthorized users from accessing restricted parts of an application, like admin panels or user accounts. This ensures only authorized users can access and change data, reducing the risk of data leaks and attacks.
|
||||
|
||||
- **Reduce Support and Incident Response Costs**
|
||||
A secure password protection system can reduce the number of support requests and incidents related to compromised accounts. This, in turn, reduces the time and resources spent on handling these issues, allowing developers to focus on improving the application and delivering new features.
|
||||
- **Reduce support and incident response costs.**
|
||||
A secure password protection system reduces support requests and issues from compromised accounts. This saves time and resources, letting developers focus on improving the application and adding new features.
|
||||
|
||||
- **Compliance with Regulations**
|
||||
Various data protection regulations and standards, such as GDPR, HIPAA, and PCI DSS, require developers to implement secure authentication mechanisms, including strong password protection. Failing to comply with these regulations can lead to legal penalties, fines, and reputational damage.
|
||||
- **Compliance with regulations**
|
||||
Various data protection regulations and standards, such as [GDPR](https://appwrite.io/blog/post/announcing-appwrite-is-gdpr-compliant), [HIPAA](https://appwrite.io/blog/post/what-is-hipaa-compliant), and PCI DSS, require developers to implement secure authentication mechanisms, including strong password protection. Failing to comply with these regulations can lead to legal penalties, fines, and reputational damage.
|
||||
|
||||
- **Preserve Brand Reputation**
|
||||
- **Preserve brand reputation**
|
||||
Data breaches and security incidents severely impact a company’s reputation, leading to a loss of user trust and potential financial losses. Developers can help protect their company’s brand and maintain customer confidence by implementing proper password protection measures.
|
||||
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ Leveraging an API-first approach, we have built a lot of abstractions to interac
|
||||
|
||||
To decrease the friction in building for all developers and complement our API-first approach, Appwrite offers over 10 SDKs across languages such as JavaScript, Python, Dart, and Kotlin, as well as a CLI that works on Linux, MacOS, and Windows-based systems.
|
||||
|
||||
- **Simplicity:** SDKs eliminate the need for developers to write code from scratch to interact with Appwrite's API, saving them time and effort.
|
||||
- **Simplicity:** SDKs eliminate the need for developers to write code from scratch to interact with Appwrite's API, saving them time and effort.
|
||||
- **Consistency and reliability**: SDKs and the CLI ensure that applications use Appwrite’s API correctly and efficiently while retaining type safety, reducing the risk of errors.
|
||||
- **Enhanced productivity:** By automating and simplifying tasks, SDKs and CLI help developers accomplish more in less time, boosting productivity. They make integrating Appwrite’s features, test applications, and deploy updates easier.
|
||||
|
||||
@@ -73,7 +73,7 @@ docker run -it --rm \
|
||||
appwrite/appwrite:1.5.7
|
||||
```
|
||||
|
||||
We have a dedicated [self-hosting guide](https://appwrite.io/docs/advanced/self-hosting) in our docs for more info.
|
||||
We have a dedicated [self-hosting guide](/docs/advanced/self-hosting) in our docs for more info.
|
||||
|
||||
## Managed databases on Appwrite Cloud
|
||||
|
||||
@@ -83,32 +83,32 @@ With Appwrite Cloud, our Database offering is fully managed. This means that our
|
||||
- **Scaling**: Resources (CPU, memory, storage) are adjusted by our team according to demand, often with minimal or no downtime.
|
||||
- **Monitoring and alerts**: There is continuous monitoring of database performance and health, with alerts for any issues, which are team takes care of.
|
||||
- **Maintenance and updates**: We handle updates to the database software and operating system, applying patches and security fixes as needed.
|
||||
- **Enhanced security:** We maintain robust security measures to protect your data.
|
||||
- **Enhanced security:** We maintain robust security measures to protect your data.
|
||||
|
||||
One of the biggest advantages of Appwrite Cloud is that these benefits are not just restricted to paid customers but also available to consumers of our free tier.
|
||||
|
||||
## Pricing plans
|
||||
|
||||
With Appwrite Cloud, we have mindfully designed our pricing plans to be accessible to most developers. Right now, we offer two [pricing plans on Appwrite Cloud](https://appwrite.io/pricing).
|
||||
With Appwrite Cloud, we have mindfully designed our pricing plans to be accessible to most developers. Right now, we offer two [pricing plans on Appwrite Cloud](/pricing).
|
||||
|
||||
- **Starter plan**
|
||||
- A free tier for every developer working on a side project or SaaS product that can thrive on our starter plan limits.
|
||||
- Free of cost
|
||||
- **Free plan**
|
||||
- A free tier for every developer working on a side project or SaaS product that can thrive on our Free plan limits.
|
||||
- Free of cost
|
||||
- **Pro plan**
|
||||
- A plan that supports your ambitions to scale your production project and allows you to grow.
|
||||
- Comes with flexible budget control tools to ensure you never get a surprise bill.
|
||||
- $15, per month, per member.
|
||||
- A plan that supports your ambitions to scale your production project and allows you to grow.
|
||||
- Comes with flexible budget control tools to ensure you never get a surprise bill.
|
||||
- $15, per month, per member.
|
||||
|
||||

|
||||
|
||||
For databases, here are the differences between both plans:
|
||||
|
||||
| Category | Starter plan | Pro plan |
|
||||
| --- | --- | --- |
|
||||
| Databases | 1 per project | Unlimited |
|
||||
| Documents | Unlimited | Unlimited |
|
||||
| Reads & Writes | Unlimited | Unlimited |
|
||||
| Dedicated databases | No | Yes |
|
||||
| Category | Free plan | Pro plan |
|
||||
| ------------------- | ------------------- | ------------------- |
|
||||
| Databases | 1 per project | Unlimited |
|
||||
| Documents | Unlimited | Unlimited |
|
||||
| Reads & Writes | Unlimited | Unlimited |
|
||||
| Dedicated databases | No | Yes |
|
||||
|
||||
You can also look at PlanetScale [pricing](https://planetscale.com/pricing) to understand how Appwrite compares.
|
||||
|
||||
@@ -116,4 +116,4 @@ You can also look at PlanetScale [pricing](https://planetscale.com/pricing) to u
|
||||
|
||||
There is no denying that PlanetScale has done a fantastic job developing a scalable and robust database offering. They are a massive inspiration in the database space and the larger developer tooling ecosystem. That being said, there are gaps in the developer community that PlanetScale chooses not to prioritize due to their business growth plans, which we can help with. Free users have formed an influential part of the Appwrite community and have made a difference not just as consumers but also as builders, public speakers, contributors, etc., who have constantly criticized and shared feedback, added ideas and suggestions, and made Appwrite a much better platform. We hope we will see more such developers give us a shot in the days to come.
|
||||
|
||||
Learn more about Appwrite by visiting our [docs](https://appwrite.io/docs) and joining our [Discord community](https://appwrite.io/discord).
|
||||
Learn more about Appwrite by visiting our [docs](/docs) and joining our [Discord community](https://appwrite.io/discord).
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
layout: post
|
||||
title: Announcing Appwrite's public roadmap
|
||||
description: We just released our product roadmap to increase transparency and foster better collaboration.
|
||||
date: 2024-06-19
|
||||
cover: /images/blog/public-roadmap-announcement/cover.png
|
||||
timeToRead: 5
|
||||
author: eldad-fux
|
||||
category: open-source
|
||||
---
|
||||
|
||||
We are excited to announce the launch of Appwrite’s public roadmap on GitHub. The new roadmap is part of our commitment to the Appwrite community and our core values of transparency and collaboration. It was one of the most highly requested features by the Appwrite community and will serve as a tool for increased collaboration among the core team, contributors, maintainers, and Appwrite developers.
|
||||
|
||||
By making our development plans public, we aim to provide our community with better visibility into our priorities, streamline the process for reporting bugs and requesting features, and align expectations around platform release timelines.
|
||||
|
||||
# Why a public roadmap?
|
||||
|
||||
## Increasing transparency
|
||||
Open communication with the community is crucial for building trust and fostering a collaborative environment. Our public roadmap will show what we are working on, what we plan to tackle next, what features or fixes are on the horizon, and what their release timelines might look like.
|
||||
|
||||
## Prioritizing community needs
|
||||
The community is the heart of Appwrite, and your feedback plays a significant role in shaping our development path. The public roadmap lets you directly influence our priorities by highlighting the most critical bugs and requested features. This guarantees that we focus on the areas that matter most to you. The Appwrite community really is the secret sauce that ensures that the Appwrite project always moves in the right direction.
|
||||
|
||||
## Aligning expectations
|
||||
We understand that knowing when new features and fixes will be available is important for planning and integrating Appwrite into your products. The public roadmap provides clear timelines and updates on our progress, helping you better plan your development cycles, communicate them to your stakeholders, and set expectations accordingly.
|
||||
|
||||
# How to use the roadmap
|
||||
|
||||
## Accessing the roadmap
|
||||
You can access our [public roadmap on GitHub](https://github.com/orgs/appwrite/projects). The roadmap is organized into different projects for each release, with issues or pull requests assigned to specific versions to indicate when we plan to complete the changes. For example, you can check out the changes planned for version 1.5.8 to see what’s coming up next.
|
||||
|
||||
## Reporting bugs and requesting features
|
||||
To report a bug or request a new feature, simply create an issue on our GitHub repository. When submitting an issue, please provide as much detail as possible, including steps to reproduce bugs and the specific needs for feature requests. This information helps our team to understand and prioritize the issue effectively.
|
||||
|
||||
## Engaging with the community
|
||||
The public roadmap is not just a tool for visibility but also a platform for collaboration. You can comment on existing issues, provide additional context, and even contribute to discussions around feature development. By upvoting bugs or features requests on GitHub you help us prioritize between the different issues and pull requests. Your insights and contributions are invaluable in helping us build a better Appwrite.
|
||||
|
||||
## Staying updated
|
||||
We encourage you to check the public roadmap regularly to stay updated on our progress. You can also watch the repository to receive notifications about new issues, updates, and releases. This way, you will always be in the loop about what’s happening with Appwrite.
|
||||
|
||||
## Flexibility and future planning
|
||||
While the new roadmap offers much more flexibility and visibility into our short-term and mid-term plans, it might still miss some bigger, longer-term projects or milestones that are in the early planning stages or going through an internal or external RFC (Request for Comments) process. These initiatives require more detailed planning and consultation before they can be added to the public roadmap.
|
||||
|
||||
# The roadmap framework
|
||||
To ensure our focus is always on the right areas, we have developed an internal framework to guide our roadmap decisions. This framework is based on the significance of our focus areas, allowing us to set clear priorities, measure progress, understand the impact, maintain balance, and foster collaboration within the team and the Appwrite community.
|
||||
|
||||

|
||||
|
||||
By concentrating on specific aspects, we ensure our team stays aligned and works towards common goals that reflect our mission while continually improving the overall developer experience. Our roadmap framework revolves around four main pillars:
|
||||
|
||||
1. **Friction**: Make it easier for developers to adopt and succeed with Appwrite by streamlining our processes and improving the overall developer experience.
|
||||
2. **Reliability**: Ensure Appwrite is a reliable, scalable, high-performing solution for all users.
|
||||
3. **Growth**: Expand Appwrite’s product offerings, enabling more growth-led activities and catering to a broader range of use cases.
|
||||
4. **Revenue**: Ensure the long-term success and sustainability of Appwrite. Business success is crucial for a better platform and ecosystem for the entire Appwrite community.
|
||||
|
||||
These four focus areas help us prioritize, make decisions, and ensure we move toward a better future for Appwrite and the Appwrite community.
|
||||
|
||||
# This is a journey
|
||||
We look forward to taking this step towards greater transparency and collaboration, and we invite you to join us on this journey. Your feedback, ideas, and participation are crucial in making Appwrite the best it can be. Together, we can build a more robust, reliable, and feature-rich platform. The platform developers deserve to have.
|
||||
|
||||
Thank you for being a part of the Appwrite community. We look forward to your contributions and continued support.
|
||||
@@ -51,7 +51,7 @@ The content of the messages plays a crucial role. Here are some best practices t
|
||||
|
||||
# Enabling push notifications for your app using Appwrite
|
||||
|
||||
The newly released Appwrite Messaging substantially simplifies your process of sending out push notifications to your application’s users. We have added simple-to-use adapters for Firebase Cloud Messaging (FCM) and Apple Push Notification Service (APNS) to let you send push notifications to let you send push notifications to both Android and iOS users.
|
||||
The newly released Appwrite Messaging substantially simplifies your process of sending out push notifications to your application’s users. We have added simple-to-use adapters for Firebase Cloud Messaging (FCM) and Apple Push Notification Service (APNS) to let you send push notifications to let you send push notifications to both Android and iOS users.
|
||||
|
||||
```server-nodejs
|
||||
const sdk = require('node-appwrite');
|
||||
@@ -78,8 +78,8 @@ const message = await messaging.createPush(
|
||||
|
||||
Visit our documentation to learn more about push notifications, join us on Discord to be part of the discussion, view our blog and YouTube channel, or visit our GitHub repository to see our open-source code.
|
||||
|
||||
- [Docs](https://appwrite.io/docs/products/messaging/send-push-notifications)
|
||||
- [Docs](/docs/products/messaging/send-push-notifications)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
- [GitHub](https://github.com/appwrite/appwrite)
|
||||
|
||||
@@ -23,12 +23,12 @@ To help you and your users avoid filling out giant forms, we're going to build a
|
||||
that will extract the total amount from a receipt image using a Hugging Face model.
|
||||
|
||||
# Prerequisites
|
||||
Before you start, you'll need to know the basics of working with Appwrite Cloud and [Appwrite Functions](https://appwrite.io/docs/products/functions).
|
||||
We're going to be using Appwrite Functions to run our receipt processing code, which calls a [Hugging Face model](https://huggingface.co/AdamCodd/donut-receipts-extract)
|
||||
Before you start, you'll need to know the basics of working with Appwrite Cloud and [Appwrite Functions](/docs/products/functions).
|
||||
We're going to be using Appwrite Functions to run our receipt processing code, which calls a [Hugging Face model](https://huggingface.co/AdamCodd/donut-receipts-extract)
|
||||
to extract data from a receipt image. Make sure you also have a **Hugging Face API key** to use the model.
|
||||
|
||||
# Scanning receipts
|
||||
We're going to use the [Hugging Face Donut Receipts Extract model](https://huggingface.co/AdamCodd/donut-receipts-extract) to
|
||||
# Scanning receipts
|
||||
We're going to use the [Hugging Face Donut Receipts Extract model](https://huggingface.co/AdamCodd/donut-receipts-extract) to
|
||||
extract relevant information from the receipt image.
|
||||
|
||||
Hugging Face's API makes this pretty simple. We'll send a POST request to the model's endpoint with the image data, and it will return the extracted information.
|
||||
@@ -219,7 +219,7 @@ Next, we'll download the file from Appwrite Storage and run our receipt scanning
|
||||
# Make a request
|
||||
Now that our function is set up, we can make a request to it from our app to scan a receipt.
|
||||
|
||||
Using a CURL request on the function's [domain](https://appwrite.io/docs/products/functions/domains):
|
||||
Using a CURL request on the function's [domain](/docs/products/functions/domains):
|
||||
```bash
|
||||
curl -X POST https://66325723b6d05e9f6262.appwrite.global \
|
||||
-H "Content-Type: application/json" \
|
||||
@@ -263,7 +263,7 @@ const result = await functions.createExecution(
|
||||
false, // async (optional)
|
||||
'/', // path (optional)
|
||||
sdk.ExecutionMethod.POST, // method
|
||||
{"Content-Type": "application/json"} // headers
|
||||
{"Content-Type": "application/json"} // headers
|
||||
);
|
||||
```
|
||||
|
||||
@@ -278,9 +278,9 @@ instead of returning it as a response.
|
||||
|
||||
Visit our documentation to learn more about Appwrite, join us on Discord to be part of the discussion, view our blog and YouTube channel, or visit our GitHub repository to see our open-source code.
|
||||
|
||||
- [Docs](https://appwrite.io/docs/products/ai)
|
||||
- [Docs](/docs/products/ai)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
- [GitHub](https://github.com/appwrite/appwrite)
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ In terms of scalability, some common challenges faced are:
|
||||
|
||||
# How Twilio can simplify implementation
|
||||
|
||||
[Twilio](https://www.notion.so/How-tools-like-Twilio-can-simplify-messaging-for-developers-9475a3f11992419c9266cf8af703c95e?pvs=21) is a cloud communications platform that offers a wide range of services, including SMS, voice, video, and email. It's known for its flexibility, scalability, and ease of integration into various applications. Twilio also provides a robust push notification service, part of its broader suite of communication tools.
|
||||
[Twilio](https://www.notion.so/How-tools-like-Twilio-can-simplify-messaging-for-developers-9475a3f11992419c9266cf8af703c95e?pvs=21) is a cloud communications platform that offers a wide range of services, including SMS, voice, video, and email. It's known for its flexibility, scalability, and ease of integration into various applications. Twilio also provides a robust push notification service, part of its broader suite of communication tools.
|
||||
|
||||
Here are some of the benefits of using Twilio:
|
||||
|
||||
@@ -53,7 +53,7 @@ One of Twilio’s products that lets developers implement messaging across vario
|
||||
|
||||
## Twilio Programmable Messaging
|
||||
|
||||
Twilio Programmable Messaging allows you to send alerts, notifications, promotions, and marketing messages to your customers' preferred channels using a single API.
|
||||
Twilio Programmable Messaging allows you to send alerts, notifications, promotions, and marketing messages to your customers' preferred channels using a single API.
|
||||
|
||||
Since the offering leverages a RESTful API, it is compatible with various programming languages and frameworks. It utilizes webhooks for real-time notifications of message delivery status and inbound messages. Security features like HTTPS and API keys ensure secure message transmission. Additionally, the Messaging API automatically queues messages when sending high volumes or when rate limits are reached.
|
||||
|
||||
@@ -97,8 +97,8 @@ const promise = await messaging.updateTwilioProvider(
|
||||
# Resources
|
||||
Visit our documentation to learn more about Messaging, join us on Discord to be part of the discussion, view our blog and YouTube channel, or visit our GitHub repository to see our open-source code.
|
||||
|
||||
- [Docs](https://appwrite.io/docs/products/messaging/twilio)
|
||||
- [Docs](/docs/products/messaging/twilio)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
- [GitHub](https://github.com/appwrite/appwrite)
|
||||
|
||||
@@ -172,8 +172,8 @@ Each of these options has its own use cases, and the choice ultimately depends o
|
||||
|
||||
In addition to simplifying your collection management, database relationships also provide several other benefits. First, they can help to ensure data consistency and integrity by enforcing referential constraints between related collections. This means that you can prevent orphaned documents or other data inconsistencies that might arise if you were to manage the relationships between collections manually. Additionally, using relationships can also improve the performance of your requests and reduce the amount of code you need to write, since you can retrieve related data in a single request rather than having to fetch it separately.
|
||||
|
||||
Overall, database relationships are a powerful tool that simplifies your collection management and saves you time and effort. By easily linking your collections and retrieving related data, you can focus on developing your application's core features. Check out the [docs](https://appwrite.io/docs/databases-relationships) for more information. We encourage you to give it a try today and see how it can benefit your development process.
|
||||
Overall, database relationships are a powerful tool that simplifies your collection management and saves you time and effort. By easily linking your collections and retrieving related data, you can focus on developing your application's core features. Check out the [docs](/docs/databases-relationships) for more information. We encourage you to give it a try today and see how it can benefit your development process.
|
||||
|
||||
- [Appwrite GitHub](https://github.com/appwrite)
|
||||
- [Appwrite Docs](https://appwrite.io/docs)
|
||||
- [Appwrite Docs](/docs)
|
||||
- [Discord Community](https://appwrite.io/discord)
|
||||
|
||||
@@ -46,10 +46,10 @@ Developers have several alternative authentication methods at their disposal, of
|
||||
- **Smart cards and USB keys**: Physical devices like smart cards or USB keys can be used for authentication. They provide a high level of security but require users to have the physical device on hand.
|
||||
- **Federated identity**: This involves linking the user's identity across multiple systems and services, allowing for the portability of identity and personal information. It's complex to implement but offers a seamless user experience. One major platform that leverages this method is Mastodon.
|
||||
|
||||
Of these methods, Appwrite offers email-password authentication, magic links, and OTP-based authentication as a part of its suite of authentication offerings. You can learn more about them in [Appwrite’s documentation](https://appwrite.io/docs/products/auth).
|
||||
Of these methods, Appwrite offers email-password authentication, magic links, and OTP-based authentication as a part of its suite of authentication offerings. You can learn more about them in [Appwrite’s documentation](/docs/products/auth).
|
||||
|
||||
# Moving forward
|
||||
|
||||
Social media login is convenient but has privacy and security issues. It's important for both users and developers to understand these risks. Fortunately, there are other ways to log in, like using email and password, biometric data, magic links, etc. These alternatives can protect user privacy better in certain circumstances and reduce dependence on social media platforms. Ultimately, the choice of authentication method should be guided by a thorough understanding of its benefits and limitations, always with the end user's best interests in mind.
|
||||
|
||||
Learn more about Appwrite Authentication from our [docs](https://appwrite.io/docs/products/auth) and join our [Discord community](https://appwrite.io/discord) to interact with fellow developers using the same.
|
||||
Learn more about Appwrite Authentication from our [docs](/docs/products/auth) and join our [Discord community](https://appwrite.io/discord) to interact with fellow developers using the same.
|
||||
@@ -43,7 +43,7 @@ The JSON would look like this under ideal situations.
|
||||
},
|
||||
... more profiles
|
||||
],
|
||||
"count": 15
|
||||
"count": 15
|
||||
}
|
||||
```
|
||||
|
||||
@@ -131,7 +131,7 @@ In Dart 2, without null safety, this code will happily compile and run. Well, un
|
||||
}
|
||||
```
|
||||
|
||||
This will give you an unexpected runtime error. If you’re building integrations or new APIs with Appwrite functions, you’d want to gracefully handle the null values instead of seeing this error in your logs.
|
||||
This will give you an unexpected runtime error. If you’re building integrations or new APIs with Appwrite functions, you’d want to gracefully handle the null values instead of seeing this error in your logs.
|
||||
|
||||
```dart
|
||||
The getter 'age' was called on null.
|
||||
@@ -155,7 +155,7 @@ Try adding either an explicit non-'null' default value or the 'required' modifie
|
||||
|
||||
While this is annoying, forcing you to explicitly handle nulls at compile times make sure you get no surprises at runtime.
|
||||
|
||||
Let’s add some null handling to our function. First, lets look at the Profile class.
|
||||
Let’s add some null handling to our function. First, lets look at the Profile class.
|
||||
|
||||
```dart
|
||||
class Profile {
|
||||
@@ -294,8 +294,8 @@ If you’re still on Dart 2.x, I strongly recommend you migrate to Dart 3 to ben
|
||||
|
||||
Visit our documentation to learn more about Dart, join us on Discord to be part of the discussion, view our blog and YouTube channel, or visit our GitHub repository to see our open-source code.
|
||||
|
||||
- [Docs](https://appwrite.io/docs/products/functions/runtimes)
|
||||
- [Docs](/docs/products/functions/runtimes)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
- [GitHub](https://github.com/appwrite/appwrite)
|
||||
|
||||
@@ -57,5 +57,5 @@ Once you have sifted through your potential solutions, make sure to pick one tha
|
||||
One of the most important parts of that journey was working to solve problems that were important to me rather than focusing on problems imposed by other individuals or circumstances. Hackathons are very special spaces that let you create real solutions to real problems in a safe environment. As long as you spend that time learning and growing while working on problems you care about, you will go a lot further than you can possibly imagine!
|
||||
|
||||
- [Appwrite GitHub](https://github.com/appwrite)
|
||||
- [Appwrite Docs](https://appwrite.io/docs)
|
||||
- [Appwrite Docs](/docs)
|
||||
- [Discord Community](https://appwrite.io/discord)
|
||||
|
||||
@@ -15,7 +15,7 @@ Forgetting to complete one of these steps will result in errors later when tryin
|
||||
|
||||
# 1 - Add a platform
|
||||
|
||||
After creating a new project in the Appwrite console, you’ll need to add a platform in order to connect an SDK. You can add a platform from the “overview” tab under the “Add a platform” section. From here, you’ll need to choose between one of the four [client-side SDK’s](https://appwrite.io/docs/sdks#client) or generate an API key with a [server-side SDK](https://appwrite.io/docs/sdks#server).
|
||||
After creating a new project in the Appwrite console, you’ll need to add a platform in order to connect an SDK. You can add a platform from the “overview” tab under the “Add a platform” section. From here, you’ll need to choose between one of the four [client-side SDK’s](/docs/sdks#client) or generate an API key with a [server-side SDK](/docs/sdks#server).
|
||||
|
||||
If you’re adding an API key to use one of the server SDK’s, you’ll be asked to set scopes for the key. This sets permissions, allowing us to dictate what permissions this API key has over certain parts of our application.
|
||||
|
||||
@@ -23,7 +23,7 @@ If you’re adding an API key to use one of the server SDK’s, you’ll be aske
|
||||
|
||||
# 2 - Add a hostname
|
||||
|
||||
When using the Web SDK, you’ll need to set a hostname. This just tells Appwrite what origin you’ll be connecting from. Failing to set the right hostname will result in CORS error later, so be sure you pay attention when setting this. I just put out a full video and [article](https://appwrite.io/blog/post/cors-error) on this topic, so be sure to check that out if you have questions or face any problems.
|
||||
When using the Web SDK, you’ll need to set a hostname. This just tells Appwrite what origin you’ll be connecting from. Failing to set the right hostname will result in CORS error later, so be sure you pay attention when setting this. I just put out a full video and [article](/blog/post/cors-error) on this topic, so be sure to check that out if you have questions or face any problems.
|
||||
|
||||

|
||||
|
||||
@@ -38,7 +38,7 @@ With these three steps to complete, you should be set to connect to an Appwrite
|
||||
# Resources
|
||||
Visit our documentation to get started, join us on Discord to be part of the discussion, or visit our blog and YouTube channel to learn more!
|
||||
|
||||
- [Docs](https://appwrite.io/docs)
|
||||
- [Docs](/docs)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
|
||||
@@ -65,7 +65,7 @@ To remove records from a table, you use deletion queries. While powerful, they s
|
||||
|
||||
# Querying the Appwrite Database
|
||||
|
||||
A lot of developers today don’t perform raw SQL queries but prefer to use an ORM such as Prima or a managed database provider such as Appwrite. While these tools enable the same end goal, a managed service can provide an easy-to-use wrapper and helper methods that make these queries easier to write and don’t require you to have a deep knowledge of SQL syntax. Appwrite offers the aforementioned data queries as a part of our Database product, which you can discover in our [product documentation](https://appwrite.io/docs/products/databases).
|
||||
A lot of developers today don’t perform raw SQL queries but prefer to use an ORM such as Prima or a managed database provider such as Appwrite. While these tools enable the same end goal, a managed service can provide an easy-to-use wrapper and helper methods that make these queries easier to write and don’t require you to have a deep knowledge of SQL syntax. Appwrite offers the aforementioned data queries as a part of our Database product, which you can discover in our [product documentation](/docs/products/databases).
|
||||
|
||||
One of the data retrieval APIs the Appwrite Database offers is a list documents API to get multiple documents from any collection. The endpoint also allows you to filter, sort, and paginate results, for which Appwrite provides a common set of syntax to build queries, which you can build manually or using our SDKs. With our latest release, we’re adding support for database operators such as `OR`, `AND`, and `CONTAINS` to allow further flexibility.
|
||||
|
||||
@@ -116,8 +116,8 @@ Mastering the art of data querying is a continuous process. As a developer, your
|
||||
|
||||
Visit our documentation to learn more about Appwrite, join us on Discord to be part of the discussion, view our blog and YouTube channel, or visit our GitHub repository to see our open-source code.
|
||||
|
||||
- [Docs](https://appwrite.io/docs/products/databases/queries)
|
||||
- [Docs](/docs/products/databases/queries)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
- [GitHub](https://github.com/appwrite/appwrite)
|
||||
|
||||
@@ -10,9 +10,9 @@ category: product
|
||||
featured: false
|
||||
---
|
||||
|
||||
When Bun announced their 1.0 release, marking Bun stable and production-ready, we excitedly began working on a Bun runtime for [Appwrite Functions](https://appwrite.io/docs/products/functions).
|
||||
When Bun announced their 1.0 release, marking Bun stable and production-ready, we excitedly began working on a Bun runtime for [Appwrite Functions](/docs/products/functions).
|
||||
|
||||
We loved the idea of Bun, because it’s more than just another Node runtime but a whole set of tools. Bun does everything from dependency management to testing and beyond with consistent DX and light-speed performance. This idea of being simple, reducing distractions, and giving developers all the tools in one place to just build stuff resonated with Appwrite’s product philosophy.
|
||||
We loved the idea of Bun, because it’s more than just another Node runtime but a whole set of tools. Bun does everything from dependency management to testing and beyond with consistent DX and light-speed performance. This idea of being simple, reducing distractions, and giving developers all the tools in one place to just build stuff resonated with Appwrite’s product philosophy.
|
||||
|
||||
Here’s a small selection of cool features that make it particularly useful as an Appwrite Function runtime.
|
||||
|
||||
@@ -195,7 +195,7 @@ describe("getGifs", () => {
|
||||
const gifUrl = await getGif(process.env['GIPHY_API_KEY']);
|
||||
expect(gifUrl).toMatch(/^(http|https):\/\/[^ "]+$/);
|
||||
});
|
||||
|
||||
|
||||
// Sanity check to make sure it will make my builds fail.
|
||||
// test("This will always fail", async () => {
|
||||
// expect(true).toBe(false);
|
||||
@@ -207,7 +207,7 @@ Each time we deploy, we can configure Appwrite Functions to run the tests after
|
||||
|
||||
```jsx
|
||||
bun install
|
||||
bun test
|
||||
bun test
|
||||
```
|
||||
|
||||
This will install dependencies and run tests before activating a deployment.
|
||||
@@ -253,7 +253,7 @@ This increased performance is particularly noticeable when you write long-runnin
|
||||
|
||||
There’s a lot to love about [Bun](https://bun.sh/), and we only explored a few exciting differences that can be leveraged in the Bun Appwrite Function runtime. Bun also has a built-in web server, high-performance file I/O, snapshot testing, and much more to offer.
|
||||
|
||||
If you’re curious, you can also try Bun in an Appwrite Function by creating your first [Appwrite Cloud](https://cloud.appwrite.io/) project. The free Starter plan gives you access to three Functions, which lets you compare and contrast Node.js, Deno, and Bun in identical containerized environments.
|
||||
If you’re curious, you can also try Bun in an Appwrite Function by creating your first [Appwrite Cloud](https://cloud.appwrite.io/) project. The free Free plan gives you access to three Functions, which lets you compare and contrast Node.js, Deno, and Bun in identical containerized environments.
|
||||
|
||||
You can try your first Bun, Node.js, or Deno function on Appwrite Cloud without writing a single line of code through Appwrite Function templates. Appwrite will clone template functions to your GitHub profile and set up automatic deployments so you can start building immediately.
|
||||
|
||||
@@ -261,8 +261,8 @@ You can try your first Bun, Node.js, or Deno function on Appwrite Cloud without
|
||||
|
||||
Visit our documentation to learn more about the Bun, join us on Discord to be part of the discussion, view our blog and YouTube channel, or visit our GitHub repository to see our open-source code.
|
||||
|
||||
- [Docs](https://appwrite.io/docs/products/functions/runtimes)
|
||||
- [Docs](/docs/products/functions/runtimes)
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Blog](https://appwrite.io/blog)
|
||||
- [Blog](/blog)
|
||||
- [YouTube](https://www.youtube.com/channel/UCtBJ1v69gm8NgbCju_03Fiw)
|
||||
- [GitHub](https://github.com/appwrite/appwrite)
|
||||
- [GitHub](https://github.com/appwrite/appwrite)
|
||||
|
||||
@@ -3,23 +3,42 @@ import { posts } from '../content';
|
||||
|
||||
export const prerender = true;
|
||||
|
||||
function encodeText(str: string | null): string {
|
||||
if (str === null) return '';
|
||||
|
||||
return str.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
}
|
||||
|
||||
function encodeUrl(href: string): string {
|
||||
return encodeURI(`https://appwrite.io${href}`)
|
||||
}
|
||||
|
||||
export const GET: RequestHandler = () => {
|
||||
const feed = `<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Appwrite</title>
|
||||
<link>https://appwrite.io</link>
|
||||
<atom:link href="https://appwrite.io/blog/rss.xml" rel="self" type="application/rss+xml" />
|
||||
<description>Appwrite is an open-source platform for building applications at any scale, using your preferred programming languages and tools.</description>
|
||||
${posts.map((post) => `<item>
|
||||
<title>${post.title}</title>
|
||||
<title>${encodeText(post.title)}</title>
|
||||
<pubDate>${post.date.toUTCString()}</pubDate>
|
||||
<link>https://appwrite.io${post.href}</link>
|
||||
<guid>https://appwrite.io${post.href}</guid>
|
||||
<description>${post.description}</description>
|
||||
<link>${encodeUrl(post.href)}</link>
|
||||
<guid>${encodeUrl(post.href)}</guid>
|
||||
<description>${encodeText(post.description)}</description>
|
||||
</item>
|
||||
`).join('')}
|
||||
</channel>
|
||||
</rss>`;
|
||||
|
||||
return new Response(feed);
|
||||
return new Response(feed, {
|
||||
headers: {
|
||||
'Content-Type': 'application/rss+xml'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -7,12 +7,12 @@ cover: /images/changelog/2023-12-20.png
|
||||
|
||||
Appwrite Pro is now available for Appwrite Cloud developers.
|
||||
|
||||
Previously, all Appwrite Cloud developers used the Starter plan with unrestricted resources.
|
||||
Previously, all Appwrite Cloud developers used the Free plan with unrestricted resources.
|
||||
With Pro, you can choose between two different plans for your organization(s):
|
||||
|
||||
- Starter: a free plan that provides an easy starting point for budding projects
|
||||
- Pro: for developers who need more resources to scale their apps,
|
||||
customized branding in emails and messages, more team members per organization, and premium support.
|
||||
- Free: a free plan that provides an easy starting point for budding projects
|
||||
- Pro: for developers who need more resources to scale their apps,
|
||||
customized branding in emails and messages, more team members per organization, and premium support.
|
||||
|
||||
{% arrow_link href="/blog/post/announcing-appwrite-pro" %}
|
||||
Read the full announcement
|
||||
|
||||
@@ -29,7 +29,7 @@ Fixes:
|
||||
- Fix file size default limit
|
||||
- Fix: Python failing builds
|
||||
- Fix shared project delete
|
||||
- Fix TextMagic class name
|
||||
- Fix Textmagic class name
|
||||
- Prevent functions domain and subdomain to be added as custom domain
|
||||
- Fix don't publish max users exceed
|
||||
- Fix invalid cache document id
|
||||
|
||||
12
src/routes/changelog/(entries)/2024-06-19.markdoc
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
layout: changelog
|
||||
title: Announcing Appwrite's public roadmap
|
||||
date: 2024-06-19
|
||||
cover: /images/changelog/2024-06-19.png
|
||||
---
|
||||
|
||||
We are excited to announce the launch of Appwrite’s public roadmap on GitHub. The new roadmap is part of our commitment to the Appwrite community and our core values of transparency and collaboration. It was one of the most highly requested features by the Appwrite community and will serve as a tool for increased collaboration among the core team, contributors, maintainers, and Appwrite developers.
|
||||
|
||||
{% arrow_link href="/blog/post/public-roadmap-announcement" %}
|
||||
Read the announcement to learn more
|
||||
{% /arrow_link %}
|
||||
@@ -6,10 +6,11 @@
|
||||
src: '/images/community/events/28march-office-hours.png',
|
||||
alt: ''
|
||||
},
|
||||
date: 'March 28th, 2024',
|
||||
date: '2024-03-28',
|
||||
location: 'Discord',
|
||||
title: 'Office Hours: Ask me anything!',
|
||||
description: 'Join us for another round of Office Hours, where we answer your questions and geek out on everything tech and Appwrite!',
|
||||
description:
|
||||
'Join us for another round of Office Hours, where we answer your questions and geek out on everything tech and Appwrite!',
|
||||
buttonText: 'View event'
|
||||
},
|
||||
{
|
||||
@@ -18,10 +19,11 @@
|
||||
src: '/images/community/events/4april-office-hours.png',
|
||||
alt: ''
|
||||
},
|
||||
date: 'April 4th, 2024',
|
||||
date: '2024-04-04',
|
||||
location: 'Discord',
|
||||
title: 'Office Hours: Ask me anything!',
|
||||
description: 'Join us for another round of Office Hours, where we answer your questions and geek out on everything tech and Appwrite!',
|
||||
description:
|
||||
'Join us for another round of Office Hours, where we answer your questions and geek out on everything tech and Appwrite!',
|
||||
buttonText: 'View event'
|
||||
},
|
||||
{
|
||||
@@ -30,10 +32,11 @@
|
||||
src: '/images/community/events/11april-office-hours.png',
|
||||
alt: ''
|
||||
},
|
||||
date: 'April 11th, 2024',
|
||||
date: '2024-04-11',
|
||||
location: 'Discord',
|
||||
title: 'Office Hours: Ask me anything!',
|
||||
description: 'Join us for another round of Office Hours, where we answer your questions and geek out on everything tech and Appwrite!',
|
||||
description:
|
||||
'Join us for another round of Office Hours, where we answer your questions and geek out on everything tech and Appwrite!',
|
||||
buttonText: 'View event'
|
||||
}
|
||||
];
|
||||
@@ -181,7 +184,8 @@
|
||||
>
|
||||
<span aria-hidden="true" class="web-icon-star" />
|
||||
<span>Star on GitHub</span>
|
||||
<span class="web-inline-tag web-sub-body-400">{GITHUB_STARS}</span
|
||||
<span class="web-inline-tag web-sub-body-400"
|
||||
>{GITHUB_STARS}</span
|
||||
>
|
||||
</a>
|
||||
</div>
|
||||
@@ -453,7 +457,9 @@
|
||||
<div class="web-big-padding-section-level-2">
|
||||
<div class="web-container">
|
||||
<div class="web-hero is-center">
|
||||
<h2 class="web-display web-u-color-text-primary">Inspire and get inspired</h2>
|
||||
<h2 class="web-display web-u-color-text-primary">
|
||||
Inspire and get inspired
|
||||
</h2>
|
||||
<p class="web-description web-u-margin-block-start-0">
|
||||
Visit our showcase website built with Appwrite to find inspiration for
|
||||
your projects or to showcase what you have built.
|
||||
|
||||
@@ -25,6 +25,12 @@
|
||||
export let description: $$Props['description'];
|
||||
export let buttonText: $$Props['buttonText'];
|
||||
export let headingLevel: $$Props['headingLevel'] = 5;
|
||||
const hasPast: boolean = (new Date()) > (new Date(date));
|
||||
const dateString: string = new Date(date).toLocaleDateString('en-US', {
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
year: 'numeric',
|
||||
});
|
||||
$: headingTag = `h${headingLevel}`;
|
||||
</script>
|
||||
|
||||
@@ -36,7 +42,7 @@
|
||||
<ul class="u-flex u-flex-wrap web-u-list-inline-dot-sep">
|
||||
<li class="u-flex u-cross-baseline u-gap-4">
|
||||
<span class="web-icon-calendar web-u-color-text-tertiary" aria-hidden="true" />
|
||||
<time class="">{date}</time>
|
||||
<time class="">{dateString}</time>
|
||||
</li>
|
||||
<li class="u-flex u-cross-baseline u-gap-4">
|
||||
<span class="web-icon-location web-u-color-text-tertiary" aria-hidden="true" />
|
||||
@@ -53,12 +59,9 @@
|
||||
{description}
|
||||
</p>
|
||||
<div class="u-flex u-flex-wrap u-gap-8 u-padding-block-start-16 mbs-auto">
|
||||
<button class="web-button is-secondary">
|
||||
<button class="web-button is-secondary" disabled={hasPast}>
|
||||
<span>{buttonText}</span>
|
||||
</button>
|
||||
<!-- <button class="web-button is-text">
|
||||
<span>Add to calendar</span>
|
||||
</button> -->
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
@@ -111,6 +111,11 @@
|
||||
label: 'Assistant',
|
||||
href: '/docs/tooling/assistant',
|
||||
icon: 'icon-sparkles'
|
||||
},
|
||||
{
|
||||
label: "The Appwriter",
|
||||
href: '/docs/tooling/appwriter',
|
||||
icon: 'icon-text'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1,111 +1,115 @@
|
||||
<script lang="ts">
|
||||
import Docs from '$lib/layouts/Docs.svelte';
|
||||
import Sidebar, { type NavParent, type NavTree } from '$lib/layouts/Sidebar.svelte';
|
||||
import Docs from '$lib/layouts/Docs.svelte';
|
||||
import Sidebar, { type NavParent, type NavTree } from '$lib/layouts/Sidebar.svelte';
|
||||
|
||||
const parent: NavParent = {
|
||||
href: '/docs',
|
||||
label: 'Platform'
|
||||
};
|
||||
const parent: NavParent = {
|
||||
href: '/docs',
|
||||
label: 'Platform'
|
||||
};
|
||||
|
||||
const navigation: NavTree = [
|
||||
{
|
||||
label: 'Platform',
|
||||
items: [
|
||||
{
|
||||
label: 'Overview',
|
||||
href: '/docs/advanced/platform'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Integration',
|
||||
items: [
|
||||
{
|
||||
label: 'Events',
|
||||
href: '/docs/advanced/platform/events'
|
||||
},
|
||||
{
|
||||
label: 'Webhooks',
|
||||
href: '/docs/advanced/platform/webhooks'
|
||||
},
|
||||
{
|
||||
label: 'Response codes',
|
||||
href: '/docs/advanced/platform/response-codes',
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Access control',
|
||||
items: [
|
||||
{
|
||||
label: 'Permissions',
|
||||
href: '/docs/advanced/platform/permissions'
|
||||
},
|
||||
{
|
||||
label: 'Rate limits',
|
||||
href: '/docs/advanced/platform/rate-limits'
|
||||
},
|
||||
{
|
||||
label: 'API keys',
|
||||
href: '/docs/advanced/platform/api-keys'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Plans',
|
||||
items: [
|
||||
{
|
||||
label: 'Billing',
|
||||
href: '/docs/advanced/platform/billing'
|
||||
},
|
||||
{
|
||||
label: 'Starter',
|
||||
href: '/docs/advanced/platform/starter'
|
||||
},
|
||||
{
|
||||
label: 'Pro',
|
||||
href: '/docs/advanced/platform/pro'
|
||||
},
|
||||
{
|
||||
label: 'Scale',
|
||||
href: '/docs/advanced/platform/scale'
|
||||
},
|
||||
{
|
||||
label: 'Enterprise',
|
||||
href: '/docs/advanced/platform/enterprise'
|
||||
},
|
||||
{
|
||||
label: 'Open source',
|
||||
href: '/docs/advanced/platform/oss'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Configuration',
|
||||
items: [
|
||||
{
|
||||
label: 'Custom domains',
|
||||
href: '/docs/advanced/platform/custom-domains'
|
||||
},
|
||||
{
|
||||
label: 'Message templates',
|
||||
href: '/docs/advanced/platform/message-templates'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Policy',
|
||||
items: [
|
||||
{
|
||||
label: 'Release policy',
|
||||
href: '/docs/advanced/platform/release-policy'
|
||||
},
|
||||
]
|
||||
}
|
||||
];
|
||||
const navigation: NavTree = [
|
||||
{
|
||||
label: 'Platform',
|
||||
items: [
|
||||
{
|
||||
label: 'Overview',
|
||||
href: '/docs/advanced/platform'
|
||||
},
|
||||
{
|
||||
label: 'Shortcuts',
|
||||
href: '/docs/advanced/platform/shortcuts'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Integration',
|
||||
items: [
|
||||
{
|
||||
label: 'Events',
|
||||
href: '/docs/advanced/platform/events'
|
||||
},
|
||||
{
|
||||
label: 'Webhooks',
|
||||
href: '/docs/advanced/platform/webhooks'
|
||||
},
|
||||
{
|
||||
label: 'Response codes',
|
||||
href: '/docs/advanced/platform/response-codes'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Access control',
|
||||
items: [
|
||||
{
|
||||
label: 'Permissions',
|
||||
href: '/docs/advanced/platform/permissions'
|
||||
},
|
||||
{
|
||||
label: 'Rate limits',
|
||||
href: '/docs/advanced/platform/rate-limits'
|
||||
},
|
||||
{
|
||||
label: 'API keys',
|
||||
href: '/docs/advanced/platform/api-keys'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Plans',
|
||||
items: [
|
||||
{
|
||||
label: 'Billing',
|
||||
href: '/docs/advanced/platform/billing'
|
||||
},
|
||||
{
|
||||
label: 'Free',
|
||||
href: '/docs/advanced/platform/free'
|
||||
},
|
||||
{
|
||||
label: 'Pro',
|
||||
href: '/docs/advanced/platform/pro'
|
||||
},
|
||||
{
|
||||
label: 'Scale',
|
||||
href: '/docs/advanced/platform/scale'
|
||||
},
|
||||
{
|
||||
label: 'Enterprise',
|
||||
href: '/docs/advanced/platform/enterprise'
|
||||
},
|
||||
{
|
||||
label: 'Open source',
|
||||
href: '/docs/advanced/platform/oss'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Configuration',
|
||||
items: [
|
||||
{
|
||||
label: 'Custom domains',
|
||||
href: '/docs/advanced/platform/custom-domains'
|
||||
},
|
||||
{
|
||||
label: 'Message templates',
|
||||
href: '/docs/advanced/platform/message-templates'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Policy',
|
||||
items: [
|
||||
{
|
||||
label: 'Release policy',
|
||||
href: '/docs/advanced/platform/release-policy'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
||||
<Docs variant="two-side-navs">
|
||||
<Sidebar {navigation} {parent} />
|
||||
<slot />
|
||||
<Sidebar {navigation} {parent} />
|
||||
<slot />
|
||||
</Docs>
|
||||
|
||||