Merge branch 'main' into feat-add-messaging-products-section
@@ -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
|
||||
|
||||
14
.github/workflows/tests.yml
vendored
@@ -1,22 +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
|
||||
node-version: 20
|
||||
- name: Install pnpm
|
||||
run: corepack enable
|
||||
- name: Get pnpm store directory
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
2
.gitignore
vendored
@@ -13,3 +13,5 @@ vite.config.ts.timestamp-*
|
||||
package-lock.json
|
||||
.tool-versions
|
||||
.vscode
|
||||
# Sentry Config File
|
||||
.sentryclirc
|
||||
|
||||
63
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,29 +243,56 @@ 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
|
||||
{% /cards_item %}
|
||||
|
||||
{% cards_item href="/docs/quick-starts/vue" title="Vue.js" %}
|
||||
Get started with Appwrite and Vue.js
|
||||
{% /cards_item %}
|
||||
|
||||
{% cards_item href="/docs/quick-starts/nuxt" title="Nuxt" %}
|
||||
Get started with Appwrite and Nuxt
|
||||
{% /cards_item %}
|
||||
|
||||
{% cards_item href="/docs/quick-starts/sveltekit" title="SvelteKit" %}
|
||||
Get started with Appwrite and SvelteKit
|
||||
{% /cards_item %}
|
||||
|
||||
{% /cards %}
|
||||
```
|
||||
|
||||
#### 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" %}
|
||||
|
||||
{% /accordion_item %}
|
||||
{% accordion_item title="Bundle ID" %}
|
||||
|
||||
{% accordion_item title="Bundle ID" %}
|
||||
{% /accordion_item %}
|
||||
{% /accordion %}
|
||||
```
|
||||
|
||||
@@ -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
|
||||
```
|
||||
@@ -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).
|
||||
|
||||
35
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,24 +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
|
||||
|
||||
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
|
||||
|
||||
EXPOSE 3000
|
||||
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
|
||||
|
||||
66
package.json
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "website-svelte",
|
||||
"name": "appwrite-website",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
@@ -20,55 +20,55 @@
|
||||
"test:integration": "playwright test",
|
||||
"test:unit": "vitest"
|
||||
},
|
||||
"packageManager": "pnpm@9.3.0",
|
||||
"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",
|
||||
"@internationalized/date": "3.5.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",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
||||
4231
pnpm-lock.yaml
generated
@@ -1,15 +1,16 @@
|
||||
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}`);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
@@ -35,10 +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: 'Messaging', href: '/products/messaging' }
|
||||
],
|
||||
Learn: [
|
||||
{ label: 'Docs', href: '/docs' },
|
||||
@@ -47,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',
|
||||
|
||||
@@ -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 = '41.7K';
|
||||
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:
|
||||
|
||||
@@ -659,6 +659,10 @@
|
||||
"link": "/docs/installation",
|
||||
"redirect": "/docs/advanced/self-hosting"
|
||||
},
|
||||
{
|
||||
"link": "/keyboard",
|
||||
"redirect": "/docs/tooling/appwriter"
|
||||
},
|
||||
{
|
||||
"link": "/careers",
|
||||
"redirect": "https://appwrite.careers"
|
||||
|
||||
@@ -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,7 +124,9 @@
|
||||
identity. Refrain from altering our logo and preferably use our
|
||||
logo on a neutral background.
|
||||
</p>
|
||||
<div class="u-flex u-flex-wrap web-u-flex-vertical-mobile 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
|
||||
@@ -233,7 +235,9 @@
|
||||
situations where space constraints make it challenging to
|
||||
showcase the complete logotype.
|
||||
</p>
|
||||
<div class="u-flex u-flex-wrap web-u-flex-vertical-mobile 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
|
||||
|
||||
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/
|
||||
---
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -58,7 +58,7 @@ Learn how to get started with [email in our documentation](/docs/products/messag
|
||||
|
||||
## SMS
|
||||
|
||||
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/).
|
||||
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.
|
||||
|
||||
|
||||
@@ -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 |
|
||||
|
||||
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)
|
||||
|
||||
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.
|
||||
@@ -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.
|
||||
@@ -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'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -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 %}
|
||||
@@ -111,6 +111,11 @@
|
||||
label: 'Assistant',
|
||||
href: '/docs/tooling/assistant',
|
||||
icon: 'icon-sparkles'
|
||||
},
|
||||
{
|
||||
label: "The Appwriter",
|
||||
href: '/docs/tooling/appwriter',
|
||||
icon: 'icon-text'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
{
|
||||
label: 'Overview',
|
||||
href: '/docs/advanced/platform'
|
||||
},
|
||||
{
|
||||
label: 'Shortcuts',
|
||||
href: '/docs/advanced/platform/shortcuts'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
69
src/routes/docs/advanced/platform/shortcuts/+page.markdoc
Normal file
@@ -0,0 +1,69 @@
|
||||
---
|
||||
layout: article
|
||||
title: Keyboard shortcuts
|
||||
description: Learn to navigate the Appwrite Console efficiently and effectively with your keyboard
|
||||
---
|
||||
|
||||
The Appwrite Console was designed with a keyboard first approach. The Appwrite Console supports keyboard shortcuts that make it easier to navigate and perform actions quicker.
|
||||
|
||||
# Shortcuts {% #shortcuts %}
|
||||
|
||||
The Appwrite Console supports keyboard shortcuts that make it easier to navigate and perform common actions quicker. The shortcuts use the following pattern: use the first letter from the call to action followed by the resource, product, service, or page you're targeting. For example, the shortcut keys `G` + `S` navigates to the project's Storage screen. Similarly, the shortcut `G` + `F` navigates to the project's Functions screen. However, when there's a conflict with a shortcut key, the following letter is used. For example, since S is already used for Storage, the shortcut for Settings is E. This pattern is used to make usage of shortcuts consistent and predictable.
|
||||
|
||||
## Global shortcuts {% #global-shortcuts %}
|
||||
|
||||
Developers can also utilize global shortcuts anywhere in the Appwrite Console, allowing instant access to these features from any page on the Console.
|
||||
|
||||
|Shortcut|Action|
|
||||
|----|----|
|
||||
|`T` then `L`|Set theme to light|
|
||||
|`T` then `D`|Set theme to dark|
|
||||
|`T` then `A`|Set theme to dark|
|
||||
|`A` then `I`|Open Appwrite Assistant|
|
||||
|`C` then `O`|Create organization|
|
||||
|
||||
## Command center
|
||||
|
||||
All the Appwrite shortcuts can be found in the [command center](/docs/tooling/command-center).
|
||||
Use the command center to search for commands or the current page's content.
|
||||
|
||||
|PC (Windows / Linux)|macOS|Action|
|
||||
|----|----|----|
|
||||
|`Ctrl` + `K`|`⌘` + `K`|Access Command Center|
|
||||
|
||||
## Project shortcuts {% #project-shortcuts %}
|
||||
|
||||
Within the context of a project, developers can utilize project shortcuts. These shortcuts are automatically enabled once a project is selected on the Console.
|
||||
These shortcuts allow quick access to the project's pages making it easier and faster to navigate the Console more.
|
||||
|
||||
|Shortcut|Action|
|
||||
|----|----|
|
||||
|`G` then `P`|Go to projects|
|
||||
|`G` then `O`|Go to overview|
|
||||
|`G` then `A`|Go to auth|
|
||||
|`G` then `D`|Go to databases|
|
||||
|`G` then `F`|Go to functions|
|
||||
|`G` then `M`|Go to messaging|
|
||||
|`G` then `S`|Go to storage|
|
||||
|`G` then `E`|Go to settings|
|
||||
|
||||
# Primary Actions
|
||||
|
||||
Each screen on the console has a concept of a primary action. For example, in the Functions screen, the primary action would be creating a function, in the Databases screen, it would be creating a database and so on. The primary actions are usually triggered using the `C` key as seen in the table below.
|
||||
|
||||
|Shortcut|Action|
|
||||
|----|----|
|
||||
|`C` then `P`|Create project|
|
||||
|`C` then `U`|Create user|
|
||||
|`C` then `A`|Create database|
|
||||
|`C` then `C`|Create collection|
|
||||
|`C` then `D`|Create document|
|
||||
|`C` then `T`|Create attribute|
|
||||
|`C` then `F`|Create function|
|
||||
|`C` then `S`|Create storage|
|
||||
|
||||
# Accessibility {% #accessibility %}
|
||||
|
||||
Using keyboard shortcuts and other methods, we are committed to making the Appwrite Console accessible to all developers by following the AA-level standards of the [Web Content Accessibility Guidelines (WCAG)](https://www.w3.org/WAI/WCAG22/Understanding/conformance#levels). Following these standards ensures that the Console is usable by people with visual, auditory, physical, speech, cognitive, language, learning, and neurological disabilities.
|
||||
|
||||
Good contrast between text and backgrounds, resizable text without loss of content or functionality, and navigable interfaces via keyboard and screen readers guarantee an inclusive environment and allow developers to perform their tasks efficiently. Adhering to these guidelines ensures that the Appwrite Console complies with legal requirements and promotes a positive developer experience for everyone.
|
||||
@@ -125,7 +125,7 @@ The example below would enable Dart 2.15, .NET 6.0, and Java 18 runtimes.
|
||||
_APP_FUNCTIONS_RUNTIMES=dart-2.15,dotnet-6.0,java-18.0
|
||||
```
|
||||
|
||||
You can find a full list of supported runtimes on the [environment variables page](/docs/advanced/self-hosting/environment-variables).
|
||||
You can find a full list of supported runtimes [here](/docs/products/functions/runtimes#available-runtimes).
|
||||
|
||||
You can also configure the maximum timeout that can be set on individual Appwrite Functions. The maximum configurable timeout can be increased by changing the `_APP_FUNCTIONS_TIMEOUT` environment variable. This environment variable changes the configurable maximum but does not alter existing configurations of individual functions.
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ Appwrite supports a growing list of SMS providers that you can choose from. Choo
|
||||
* [Documentation](https://www.twilio.com/docs/iam/access-tokens#step-2-api-key)
|
||||
---
|
||||
* {% icon icon="textmagic" size="l" /%}
|
||||
* TextMagic
|
||||
* Textmagic
|
||||
* [Website](https://www.textmagic.com)
|
||||
* [Documentation](https://www.textmagic.com/docs/api/start/#How-to-obtain-the-API-credentials)
|
||||
---
|
||||
@@ -59,7 +59,7 @@ Ensure the values you insert in the `_APP_SMS_PROVIDER` placeholders are [URL en
|
||||
| Provider | \_APP\_SMS\_PROVIDER | \_APP\_SMS\_FROM |
|
||||
| -------- | -------------------------------------------------- | ----------------------- |
|
||||
| Twilio | `sms://[ACCOUNT SID]:[AUTH TOKEN]@twilio` | `[TWILIO PHONE NUMBER]` |
|
||||
| TextMagic| `sms://[USERNAME]:[API KEY]@text-magic` | `[PHONE NUMBER OR SENDER ID]` |
|
||||
| Textmagic| `sms://[USERNAME]:[API KEY]@text-magic` | `[PHONE NUMBER OR SENDER ID]` |
|
||||
| TeleSign | `sms://[CUSTOMER ID]:[API KEY]@telesign` | `[TELESIGN PHONE NUMBER]` |
|
||||
| MSG91 | `sms://[SENDER ID]:[AUTH KEY]@msg91` | `[FLOW ID]` |
|
||||
| Vonage | `sms://[API KEY]:[API SECRET]@vonage` | `[PHONE NUMBER OR BRAND NAME]` |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
layout: article
|
||||
title: Artifical intelligence
|
||||
title: Artificial intelligence
|
||||
description: "Learn how to implement machine learning models in your applications."
|
||||
---
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ const client = new Client()
|
||||
|
||||
const account = new Account(client);
|
||||
|
||||
const user await = account.create(
|
||||
'ID.unique()',
|
||||
const user = await account.create(
|
||||
ID.unique(),
|
||||
'email@example.com',
|
||||
'password'
|
||||
);
|
||||
@@ -90,8 +90,8 @@ const client = new Client()
|
||||
|
||||
const account = new Account(client);
|
||||
|
||||
const user await = account.create(
|
||||
'ID.unique()',
|
||||
const user = await account.create(
|
||||
ID.unique(),
|
||||
'email@example.com',
|
||||
'password'
|
||||
);
|
||||
|
||||
@@ -50,6 +50,11 @@ While still in beta, Appwrite Cloud has limited support for Cloud runtimes. As w
|
||||
`python-3.12`
|
||||
* x86 / arm64 / armv7 / armv8
|
||||
---
|
||||
* {% icon icon="python" size="l" /%}
|
||||
* [Python ML](https://hub.docker.com/r/openruntimes/python-ml)
|
||||
* `python-ML-3.11`
|
||||
* x86 / arm64
|
||||
---
|
||||
* {% icon icon="dart" size="l" /%}
|
||||
* [Dart](https://hub.docker.com/r/openruntimes/dart/tags)
|
||||
* `dart-2.15`
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
href: '/docs/products/messaging/telesign'
|
||||
},
|
||||
{
|
||||
label: 'SMS with TextMagic',
|
||||
label: 'SMS with Textmagic',
|
||||
href: '/docs/products/messaging/textmagic'
|
||||
},
|
||||
{
|
||||
|
||||
@@ -57,7 +57,7 @@ Some additional configuration is required to enable push notifications in your m
|
||||
1. Add `google-services.json` at the root of your project.
|
||||
1. Add Google Services class path to your app-level Gradle dependencies block `"com.google.gms:google-services:4.4.0"`.
|
||||
1. Add Google Services plugin to your app-level Gradle in the plugins block as `"com.google.gms.google-services"`.
|
||||
1. Add notification handler service to `AndroidManifest.xml` inside the application tag, alongisde other activities. Find an example of this service in the [Send push notification](/docs/products/messaging/send-push-notifications#add-targets) journey.
|
||||
1. Add notification handler service to `AndroidManifest.xml` inside the application tag, alongside other activities. Find an example of this service in the [Send push notification](/docs/products/messaging/send-push-notifications#add-targets) journey.
|
||||
```xml
|
||||
<service android:name="<YOUR_NOTIFICATION_HANDLER_SERVICE>" android:exported="false">
|
||||
<intent-filter>
|
||||
|
||||
@@ -235,7 +235,7 @@ class MessagingService : FirebaseMessagingService() {
|
||||
|
||||
In your `AndroidManifest.xml`, register this new service.
|
||||
```xml
|
||||
<service android:name="io.appwrite.NotificationHandler" android:exported="false">
|
||||
<service android:name="<YOUR_NOTIFICATION_HANDLER_SERVICE>" android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||
</intent-filter>
|
||||
@@ -384,7 +384,6 @@ func application(
|
||||
|
||||
{% section #request-permissions step=3 title="Request permissions" %}
|
||||
Your app must ask for permission to receive push notification from the user.
|
||||
Appwrite provides an `OS` class to help simplify the process to handle permissions.
|
||||
|
||||
{% tabs %}
|
||||
{% tabsitem #apple-apns title="Apple with APNs" %}
|
||||
|
||||
@@ -10,7 +10,7 @@ This guide takes you through the implementation path of adding sms messaging to
|
||||
Appwrite supports [Twilio](/docs/products/messaging/twilio/),
|
||||
[MSG91](/docs/products/messaging/msg91/),
|
||||
[Telesign](/docs/products/messaging/telesign/),
|
||||
[TextMagic](/docs/products/messaging/textmagic/),
|
||||
[Textmagic](/docs/products/messaging/textmagic/),
|
||||
and [Vonage](/docs/products/messaging/vonage/)
|
||||
as SMS providers. You must configure one of them as a provider.
|
||||
{% only_dark %}
|
||||
@@ -24,7 +24,7 @@ and follow the wizard. You can find more details about configuring in the provid
|
||||
[Twilio](/docs/products/messaging/twilio/),
|
||||
[MSG91](/docs/products/messaging/msg91/),
|
||||
[Telesign](/docs/products/messaging/telesign/),
|
||||
[TextMagic](/docs/products/messaging/textmagic/),
|
||||
[Textmagic](/docs/products/messaging/textmagic/),
|
||||
and [Vonage](/docs/products/messaging/vonage/).
|
||||
|
||||
# Add targets {% #add-targets %}
|
||||
|
||||
@@ -71,9 +71,9 @@ Push notifications require configuration on both the Appwrite platform and your
|
||||
1. Add `google-services.json` at the root of your project.
|
||||
1. Add Google Services class path to your app-level Gradle dependencies block `"com.google.gms:google-services:4.4.0"`.
|
||||
1. Add Google Services plugin to your app-level Gradle in the plugins block as `"com.google.gms.google-services"`.
|
||||
1. Add notification handler service to `AndroidManifest.xml` inside the application tag, alongisde other activities.
|
||||
```groovy
|
||||
<service android:name="io.appwrite.NotificationHandler" android:exported="false">
|
||||
1. Add notification handler service to `AndroidManifest.xml` inside the application tag, alongside other activities. Find an example of this service in the [Send push notification](/docs/products/messaging/send-push-notifications#add-targets) journey.
|
||||
```xml
|
||||
<service android:name="<YOUR_NOTIFICATION_HANDLER_SERVICE>" android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||
</intent-filter>
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
---
|
||||
layout: article
|
||||
title: TextMagic
|
||||
description: Send SMS messages to your Appwrite users using TextMagic and Appwrite Messaging.
|
||||
title: Textmagic
|
||||
description: Send SMS messages to your Appwrite users using Textmagic and Appwrite Messaging.
|
||||
back: /docs/
|
||||
---
|
||||
TextMagic lets you send customized SMS messages to your users.
|
||||
Textmagic lets you send customized SMS messages to your users.
|
||||
These SMS messages can be sent immediately or scheduled.
|
||||
You can send SMS messages for purposes like reminders, promotions, announcements, and even custom authentication flows.
|
||||
|
||||
{% section #add-provider step=1 title="Add provider" %}
|
||||
|
||||
To add TextMagic as a provider, navigate to **Messaging** > **Providers** > {% icon icon="plus" size="m" /%} **Add provider** > **SMS**.
|
||||
To add Textmagic as a provider, navigate to **Messaging** > **Providers** > {% icon icon="plus" size="m" /%} **Add provider** > **SMS**.
|
||||
{% only_dark %}
|
||||

|
||||
{% /only_dark %}
|
||||
@@ -18,27 +18,27 @@ To add TextMagic as a provider, navigate to **Messaging** > **Providers** > {% i
|
||||

|
||||
{% /only_light %}
|
||||
|
||||
Give your provider a name > choose **TextMagic** > click **Save and continue**.
|
||||
Give your provider a name > choose **Textmagic** > click **Save and continue**.
|
||||
The provider will be saved to your project, but not enabled until you complete its configuration.
|
||||
{% /section %}
|
||||
{% section #configure-provider step=2 title="Configure provider" %}
|
||||
|
||||
In the **Configure** step, you will need to provide details from your TextMagic dashboard to connect your Appwrite project.
|
||||
In the **Configure** step, you will need to provide details from your Textmagic dashboard to connect your Appwrite project.
|
||||
|
||||
You will need to provide the following information from your **TextMagic dashboard**.
|
||||
You will need to provide the following information from your **Textmagic dashboard**.
|
||||
|
||||
{% table %}
|
||||
* Field name
|
||||
*
|
||||
---
|
||||
* API key
|
||||
* Head to TextMagic dashboard > **Services** > **API** > **Add new API key**.
|
||||
* Head to Textmagic dashboard > **Services** > **API** > **Add new API key**.
|
||||
---
|
||||
* Username
|
||||
* Head to TextMagic dashboard > **My account** > **Username**.
|
||||
* Head to Textmagic dashboard > **My account** > **Username**.
|
||||
---
|
||||
* Sender number
|
||||
* Head to TextMagic dashboard > **Services** > **Sender settings**.
|
||||
* Head to Textmagic dashboard > **Services** > **Sender settings**.
|
||||
{% /table %}
|
||||
|
||||
After adding the following details, click **Save and continue** to enable the provider.
|
||||
|
||||
9
src/routes/docs/tooling/appwriter/+layout.svelte
Normal file
@@ -0,0 +1,9 @@
|
||||
<script lang="ts">
|
||||
import Docs from '$lib/layouts/Docs.svelte';
|
||||
import Sidebar from '../../Sidebar.svelte';
|
||||
</script>
|
||||
|
||||
<Docs variant="two-side-navs">
|
||||
<Sidebar />
|
||||
<slot />
|
||||
</Docs>
|
||||
56
src/routes/docs/tooling/appwriter/+page.markdoc
Normal file
@@ -0,0 +1,56 @@
|
||||
---
|
||||
layout: article
|
||||
title: The Appwriter
|
||||
description: Learn about the custom Appwriter mechanical keyboard and its specifications
|
||||
---
|
||||
|
||||
{% only_dark %}
|
||||

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

|
||||
{% /only_light %}
|
||||
|
||||
The Appwriter is an exclusive mechanical keyboard custom-designed by the Appwrite team. It is optimized to improve developer productivity and is specially tuned to use with the Appwrite Console.
|
||||
|
||||
The Appwriter uses icons from the Appwrite Console and Docs on specific keys, making memorizing keyboard shortcuts easier. For example, `G` then `D` is the shortcut for navigating to your project's databases, and the icon on the `D` key matches the icon for Appwrite Databases.
|
||||
|
||||
# What's in the box {% #whats-in-the-box %}
|
||||
|
||||
- Appwriter keyboard
|
||||
- USB-C data/charging cable
|
||||
- 2-in-1 keycap and switch puller
|
||||
- Extra PC layout keycaps
|
||||
- Information card with a QR code
|
||||
|
||||
The keyboard comes with Mac layout keys pre-installed for macOS which can also be swapped with the included PC keycaps.
|
||||
|
||||
# Specifications {% #specifications %}
|
||||
|
||||
|Specification|Details|
|
||||
|----|----|
|
||||
|Battery|3000mAh rechargeable battery|
|
||||
|Design|75% compact design keyboard|
|
||||
|Keycaps|84 custom dye sublimated PBT keycaps|
|
||||
|Switches|Gateron G Pro yellow pre-lubed switches|
|
||||
|Connections|Tri-mode connectivity (2.4Ghz wireless / bluetooth / wired USB-C)|
|
||||
|Case|Noise dampening case-foam|
|
||||
|RGB backlight|16 Million colors & multiple lighting effects|
|
||||
|Switch support|Hot-swappable switches with 3 & 5 pin|
|
||||
|Rollover|N-key rollover|
|
||||
|
||||
# How to change the backlight {% #how-to-change-the-backlight %}
|
||||
|
||||
Press `Fn + Home` to change the RGB backlight effect and cycle through all the lights.
|
||||
|
||||
# How to get the Appwriter {% #how-to-get-the-appwriter %}
|
||||
|
||||
The Appwriter is currently exclusive to Appwrite events and giveaways.
|
||||
To get your hands on an Appwriter, look out for events & giveaways on our social media
|
||||
- [Discord](https://appwrite.io/discord)
|
||||
- [Github](https://github.com/appwrite/appwrite)
|
||||
- [X](https://x.com/appwrite)
|
||||
- [YouTube](https://www.youtube.com/c/appwrite)
|
||||
|
||||
Later this year, the Appwriter will be available for purchase in the [Appwrite Store](https://appwrite.store/).
|
||||
@@ -4,7 +4,7 @@ title: All set
|
||||
description: Add authentication to a Next.js project using Appwrite.
|
||||
step: 8
|
||||
---
|
||||
If you want to see the complete source code with styling, see the [demos-for-react](https://github.com/appwrite/demos-for-react/tree/main/nextjs/server-side-rendering) repository.
|
||||
If you want to see the complete source code with styling, see the [demos-for-react](https://github.com/appwrite/demos-for-react/tree/master/nextjs/server-side-rendering) repository.
|
||||
|
||||
# Other authentication methods {% #other-authentication-methods %}
|
||||
Appwrite also supports OAuth, passwordless login, anonymous login, and phone login.
|
||||
|
||||
@@ -10,7 +10,7 @@ step: 2
|
||||
Create a React app with the `npm create` command.
|
||||
|
||||
```sh
|
||||
npm create vite@latest --template react ideas-tracker && cd ideas-tracker
|
||||
npm create vite@latest -- --template react ideas-tracker && cd ideas-tracker
|
||||
```
|
||||
|
||||
# Add dependencies {% #add-dependencies %}
|
||||
|
||||
@@ -29,6 +29,7 @@ export function UserProvider(props) {
|
||||
async function login(email, password) {
|
||||
const loggedIn = await account.createEmailPasswordSession(email, password);
|
||||
setUser(loggedIn);
|
||||
window.location.replace("/"); // you can use different redirect method for your application
|
||||
}
|
||||
|
||||
async function logout() {
|
||||
@@ -183,4 +184,3 @@ export function Login() {
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -14,12 +14,26 @@ In Appwrite, data is stored as a collection of documents. Create a collection in
|
||||

|
||||
{% /only_light %}
|
||||
|
||||
## Attributes
|
||||
|
||||
Create a new collection with the following attributes:
|
||||
| Field | Type | Required |
|
||||
|-------------|--------|----------|
|
||||
| userId | String | Yes |
|
||||
| title | String | Yes |
|
||||
| description | String | No |
|
||||
| Field | Type | Required | Size |
|
||||
|-------------|--------|----------|--------|
|
||||
| userId | String | Yes | 50 |
|
||||
| title | String | Yes | 25 |
|
||||
| description | String | No | 100 |
|
||||
|
||||
# Configure permissions {% #configure-permissions %}
|
||||
{% only_dark %}
|
||||

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

|
||||
{% /only_light %}
|
||||
|
||||
Navigate to the **Settings** tab of your collection, add the role **Any** and check the **Read** box.
|
||||
Next, add a **Users** role and give them access to **Create** by checking those boxes.
|
||||
These permissions apply to all documents in your new collection.
|
||||
|
||||
# Ideas context {% #ideas-context %}
|
||||
|
||||
@@ -79,4 +93,3 @@ export function IdeasProvider(props) {
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -79,3 +79,29 @@ export function Home() {
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
In `src/App.jsx`, wrap the `main` element with the `IdeaProvider` component.
|
||||
|
||||
```client-web
|
||||
import { Login } from "./pages/Login";
|
||||
import { Home } from "./pages/Home";
|
||||
import { UserProvider } from "./lib/context/user";
|
||||
import { IdeaProvider } from "./lib/context/ideas";
|
||||
|
||||
function App() {
|
||||
const isLoginPage = window.location.pathname === "/login";
|
||||
|
||||
return (
|
||||
<div>
|
||||
<UserProvider>
|
||||
<IdeaProvider>
|
||||
<Navbar /> {/* Add the navbar before page content */}
|
||||
<main>{isLoginPage ? <Login /> : <Home />}</main>
|
||||
</IdeaProvider>
|
||||
<UserProvider>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
```
|
||||
@@ -14,13 +14,12 @@
|
||||
font-size: var(--web-font-size-micro);
|
||||
line-height: var(--web-line-height-tiny);
|
||||
|
||||
#{$theme-dark} & {
|
||||
--p-tag-bg-color: var(--web-color-greyscale-750);
|
||||
}
|
||||
|
||||
#{$theme-light} & {
|
||||
--p-tag-bg-color: var(--web-color-greyscale-100);
|
||||
}
|
||||
#{$theme-dark} & {
|
||||
--p-tag-bg-color: var(--web-color-greyscale-750);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
BIN
static/images/avatars/snezhanna.png
Normal file
|
After Width: | Height: | Size: 196 KiB |
BIN
static/images/blog/baas-vs-custom-backend/auth.png
Normal file
|
After Width: | Height: | Size: 160 KiB |
BIN
static/images/blog/baas-vs-custom-backend/cover.png
Normal file
|
After Width: | Height: | Size: 2.9 MiB |
BIN
static/images/blog/baas-vs-custom-backend/database.png
Normal file
|
After Width: | Height: | Size: 177 KiB |
BIN
static/images/blog/baas-vs-custom-backend/messaging.png
Normal file
|
After Width: | Height: | Size: 55 KiB |
BIN
static/images/blog/baas-vs-custom-backend/storage.png
Normal file
|
After Width: | Height: | Size: 184 KiB |
BIN
static/images/blog/developer-tools-appwrite/cover.png
Normal file
|
After Width: | Height: | Size: 2.6 MiB |
BIN
static/images/blog/public-roadmap-announcement/cover.png
Normal file
|
After Width: | Height: | Size: 2.0 MiB |
BIN
static/images/blog/public-roadmap-announcement/framework.png
Normal file
|
After Width: | Height: | Size: 609 KiB |
BIN
static/images/changelog/2024-06-19.png
Normal file
|
After Width: | Height: | Size: 2.0 MiB |
BIN
static/images/docs/keyboard/appwriter.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
static/images/docs/keyboard/dark/appwriter.png
Normal file
|
After Width: | Height: | Size: 63 KiB |
@@ -1,3 +1,4 @@
|
||||
import { sentrySvelteKit } from '@sentry/sveltekit';
|
||||
import dynamicImport from 'vite-plugin-dynamic-import';
|
||||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
import { defineConfig } from 'vitest/config';
|
||||
@@ -6,6 +7,13 @@ import { enhancedImages } from '@sveltejs/enhanced-img';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
sentrySvelteKit({
|
||||
adapter: 'node',
|
||||
sourceMapsUploadOptions: {
|
||||
org: 'appwrite',
|
||||
project: 'website'
|
||||
}
|
||||
}),
|
||||
enhancedImages(),
|
||||
sveltekit(),
|
||||
dynamicImport({
|
||||
@@ -19,6 +27,9 @@ export default defineConfig({
|
||||
includePublic: true
|
||||
})
|
||||
],
|
||||
build: {
|
||||
reportCompressedSize: false
|
||||
},
|
||||
test: {
|
||||
include: ['src/**/*.{test,spec}.{js,ts}']
|
||||
}
|
||||
|
||||