Merge branch 'main' into init-playground

This commit is contained in:
Jesse Winton
2024-07-26 13:34:05 -04:00
240 changed files with 984 additions and 481 deletions

View File

@@ -0,0 +1 @@
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M12.467 11.058 C 12.375 11.089,12.180 11.176,12.033 11.252 C 11.646 11.454,4.391 18.744,4.191 19.133 C 3.977 19.550,3.974 20.303,4.186 20.735 C 4.293 20.953,5.393 22.094,8.150 24.846 C 11.945 28.635,11.969 28.657,12.359 28.769 C 12.842 28.908,13.335 28.876,13.737 28.680 C 13.954 28.575,16.126 26.443,21.866 20.702 L 29.699 12.868 28.966 12.129 C 28.531 11.691,28.101 11.322,27.908 11.223 C 27.463 10.994,26.981 10.953,26.491 11.101 C 26.102 11.219,26.069 11.251,18.211 19.093 L 10.322 26.967 11.189 25.233 L 12.056 23.500 10.278 21.716 L 8.501 19.933 10.717 17.717 L 12.933 15.501 14.700 17.267 L 16.467 19.033 17.783 17.716 L 19.099 16.400 16.566 13.866 C 14.733 12.032,13.950 11.293,13.733 11.191 C 13.410 11.039,12.740 10.968,12.467 11.058 M28.844 14.711 L 27.989 16.422 29.761 18.195 L 31.533 19.967 28.532 22.967 C 26.392 25.105,25.489 26.053,25.385 26.266 C 25.191 26.665,25.188 27.313,25.379 27.739 C 25.681 28.413,26.326 28.829,27.067 28.829 C 27.884 28.829,27.776 28.919,31.907 24.780 C 36.005 20.674,35.947 20.743,35.953 19.967 C 35.959 19.197,35.961 19.199,32.715 15.950 C 31.094 14.327,29.752 13.000,29.733 13.000 C 29.714 13.000,29.314 13.770,28.844 14.711 " stroke="none" fill-rule="evenodd" fill="black"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -14,37 +14,38 @@ $web-icon-chevron-up: "\ea0d";
$web-icon-close: "\ea0e";
$web-icon-command: "\ea0f";
$web-icon-copy: "\ea10";
$web-icon-dark: "\ea11";
$web-icon-discord: "\ea12";
$web-icon-divider-vertical: "\ea13";
$web-icon-download: "\ea14";
$web-icon-ext-link: "\ea15";
$web-icon-firebase: "\ea16";
$web-icon-github: "\ea17";
$web-icon-google: "\ea18";
$web-icon-hamburger-menu: "\ea19";
$web-icon-light: "\ea1a";
$web-icon-linkedin: "\ea1b";
$web-icon-location: "\ea1c";
$web-icon-logout-left: "\ea1d";
$web-icon-logout-right: "\ea1e";
$web-icon-mailgun: "\ea1f";
$web-icon-message: "\ea20";
$web-icon-microsoft: "\ea21";
$web-icon-minus: "\ea22";
$web-icon-nuxt: "\ea23";
$web-icon-platform: "\ea24";
$web-icon-play: "\ea25";
$web-icon-plus: "\ea26";
$web-icon-product-hunt: "\ea27";
$web-icon-refine: "\ea28";
$web-icon-rest: "\ea29";
$web-icon-search: "\ea2a";
$web-icon-sendgrid: "\ea2b";
$web-icon-star: "\ea2c";
$web-icon-system: "\ea2d";
$web-icon-textmagic: "\ea2e";
$web-icon-twitter: "\ea2f";
$web-icon-vue: "\ea30";
$web-icon-x: "\ea31";
$web-icon-youtube: "\ea32";
$web-icon-daily-dev: "\ea11";
$web-icon-dark: "\ea12";
$web-icon-discord: "\ea13";
$web-icon-divider-vertical: "\ea14";
$web-icon-download: "\ea15";
$web-icon-ext-link: "\ea16";
$web-icon-firebase: "\ea17";
$web-icon-github: "\ea18";
$web-icon-google: "\ea19";
$web-icon-hamburger-menu: "\ea1a";
$web-icon-light: "\ea1b";
$web-icon-linkedin: "\ea1c";
$web-icon-location: "\ea1d";
$web-icon-logout-left: "\ea1e";
$web-icon-logout-right: "\ea1f";
$web-icon-mailgun: "\ea20";
$web-icon-message: "\ea21";
$web-icon-microsoft: "\ea22";
$web-icon-minus: "\ea23";
$web-icon-nuxt: "\ea24";
$web-icon-platform: "\ea25";
$web-icon-play: "\ea26";
$web-icon-plus: "\ea27";
$web-icon-product-hunt: "\ea28";
$web-icon-refine: "\ea29";
$web-icon-rest: "\ea2a";
$web-icon-search: "\ea2b";
$web-icon-sendgrid: "\ea2c";
$web-icon-star: "\ea2d";
$web-icon-system: "\ea2e";
$web-icon-textmagic: "\ea2f";
$web-icon-twitter: "\ea30";
$web-icon-vue: "\ea31";
$web-icon-x: "\ea32";
$web-icon-youtube: "\ea33";

View File

@@ -95,208 +95,214 @@
"className": "web-icon-copy",
"unicode": "&#59920;"
},
"dark": {
"daily-dev": {
"encodedCode": "\\ea11",
"prefix": "web-icon",
"className": "web-icon-dark",
"className": "web-icon-daily-dev",
"unicode": "&#59921;"
},
"discord": {
"dark": {
"encodedCode": "\\ea12",
"prefix": "web-icon",
"className": "web-icon-discord",
"className": "web-icon-dark",
"unicode": "&#59922;"
},
"divider-vertical": {
"discord": {
"encodedCode": "\\ea13",
"prefix": "web-icon",
"className": "web-icon-divider-vertical",
"className": "web-icon-discord",
"unicode": "&#59923;"
},
"download": {
"divider-vertical": {
"encodedCode": "\\ea14",
"prefix": "web-icon",
"className": "web-icon-download",
"className": "web-icon-divider-vertical",
"unicode": "&#59924;"
},
"ext-link": {
"download": {
"encodedCode": "\\ea15",
"prefix": "web-icon",
"className": "web-icon-ext-link",
"className": "web-icon-download",
"unicode": "&#59925;"
},
"firebase": {
"ext-link": {
"encodedCode": "\\ea16",
"prefix": "web-icon",
"className": "web-icon-firebase",
"className": "web-icon-ext-link",
"unicode": "&#59926;"
},
"github": {
"firebase": {
"encodedCode": "\\ea17",
"prefix": "web-icon",
"className": "web-icon-github",
"className": "web-icon-firebase",
"unicode": "&#59927;"
},
"google": {
"github": {
"encodedCode": "\\ea18",
"prefix": "web-icon",
"className": "web-icon-google",
"className": "web-icon-github",
"unicode": "&#59928;"
},
"hamburger-menu": {
"google": {
"encodedCode": "\\ea19",
"prefix": "web-icon",
"className": "web-icon-hamburger-menu",
"className": "web-icon-google",
"unicode": "&#59929;"
},
"light": {
"hamburger-menu": {
"encodedCode": "\\ea1a",
"prefix": "web-icon",
"className": "web-icon-light",
"className": "web-icon-hamburger-menu",
"unicode": "&#59930;"
},
"linkedin": {
"light": {
"encodedCode": "\\ea1b",
"prefix": "web-icon",
"className": "web-icon-linkedin",
"className": "web-icon-light",
"unicode": "&#59931;"
},
"location": {
"linkedin": {
"encodedCode": "\\ea1c",
"prefix": "web-icon",
"className": "web-icon-location",
"className": "web-icon-linkedin",
"unicode": "&#59932;"
},
"logout-left": {
"location": {
"encodedCode": "\\ea1d",
"prefix": "web-icon",
"className": "web-icon-logout-left",
"className": "web-icon-location",
"unicode": "&#59933;"
},
"logout-right": {
"logout-left": {
"encodedCode": "\\ea1e",
"prefix": "web-icon",
"className": "web-icon-logout-right",
"className": "web-icon-logout-left",
"unicode": "&#59934;"
},
"mailgun": {
"logout-right": {
"encodedCode": "\\ea1f",
"prefix": "web-icon",
"className": "web-icon-mailgun",
"className": "web-icon-logout-right",
"unicode": "&#59935;"
},
"message": {
"mailgun": {
"encodedCode": "\\ea20",
"prefix": "web-icon",
"className": "web-icon-message",
"className": "web-icon-mailgun",
"unicode": "&#59936;"
},
"microsoft": {
"message": {
"encodedCode": "\\ea21",
"prefix": "web-icon",
"className": "web-icon-microsoft",
"className": "web-icon-message",
"unicode": "&#59937;"
},
"minus": {
"microsoft": {
"encodedCode": "\\ea22",
"prefix": "web-icon",
"className": "web-icon-minus",
"className": "web-icon-microsoft",
"unicode": "&#59938;"
},
"nuxt": {
"minus": {
"encodedCode": "\\ea23",
"prefix": "web-icon",
"className": "web-icon-nuxt",
"className": "web-icon-minus",
"unicode": "&#59939;"
},
"platform": {
"nuxt": {
"encodedCode": "\\ea24",
"prefix": "web-icon",
"className": "web-icon-platform",
"className": "web-icon-nuxt",
"unicode": "&#59940;"
},
"play": {
"platform": {
"encodedCode": "\\ea25",
"prefix": "web-icon",
"className": "web-icon-play",
"className": "web-icon-platform",
"unicode": "&#59941;"
},
"plus": {
"play": {
"encodedCode": "\\ea26",
"prefix": "web-icon",
"className": "web-icon-plus",
"className": "web-icon-play",
"unicode": "&#59942;"
},
"product-hunt": {
"plus": {
"encodedCode": "\\ea27",
"prefix": "web-icon",
"className": "web-icon-product-hunt",
"className": "web-icon-plus",
"unicode": "&#59943;"
},
"refine": {
"product-hunt": {
"encodedCode": "\\ea28",
"prefix": "web-icon",
"className": "web-icon-refine",
"className": "web-icon-product-hunt",
"unicode": "&#59944;"
},
"rest": {
"refine": {
"encodedCode": "\\ea29",
"prefix": "web-icon",
"className": "web-icon-rest",
"className": "web-icon-refine",
"unicode": "&#59945;"
},
"search": {
"rest": {
"encodedCode": "\\ea2a",
"prefix": "web-icon",
"className": "web-icon-search",
"className": "web-icon-rest",
"unicode": "&#59946;"
},
"sendgrid": {
"search": {
"encodedCode": "\\ea2b",
"prefix": "web-icon",
"className": "web-icon-sendgrid",
"className": "web-icon-search",
"unicode": "&#59947;"
},
"star": {
"sendgrid": {
"encodedCode": "\\ea2c",
"prefix": "web-icon",
"className": "web-icon-star",
"className": "web-icon-sendgrid",
"unicode": "&#59948;"
},
"system": {
"star": {
"encodedCode": "\\ea2d",
"prefix": "web-icon",
"className": "web-icon-system",
"className": "web-icon-star",
"unicode": "&#59949;"
},
"textmagic": {
"system": {
"encodedCode": "\\ea2e",
"prefix": "web-icon",
"className": "web-icon-textmagic",
"className": "web-icon-system",
"unicode": "&#59950;"
},
"twitter": {
"textmagic": {
"encodedCode": "\\ea2f",
"prefix": "web-icon",
"className": "web-icon-twitter",
"className": "web-icon-textmagic",
"unicode": "&#59951;"
},
"vue": {
"twitter": {
"encodedCode": "\\ea30",
"prefix": "web-icon",
"className": "web-icon-vue",
"className": "web-icon-twitter",
"unicode": "&#59952;"
},
"x": {
"vue": {
"encodedCode": "\\ea31",
"prefix": "web-icon",
"className": "web-icon-x",
"className": "web-icon-vue",
"unicode": "&#59953;"
},
"youtube": {
"x": {
"encodedCode": "\\ea32",
"prefix": "web-icon",
"className": "web-icon-youtube",
"className": "web-icon-x",
"unicode": "&#59954;"
},
"youtube": {
"encodedCode": "\\ea33",
"prefix": "web-icon",
"className": "web-icon-youtube",
"unicode": "&#59955;"
}
}

View File

@@ -33,37 +33,38 @@
.web-icon-close:before { content: "\ea0e"; }
.web-icon-command:before { content: "\ea0f"; }
.web-icon-copy:before { content: "\ea10"; }
.web-icon-dark:before { content: "\ea11"; }
.web-icon-discord:before { content: "\ea12"; }
.web-icon-divider-vertical:before { content: "\ea13"; }
.web-icon-download:before { content: "\ea14"; }
.web-icon-ext-link:before { content: "\ea15"; }
.web-icon-firebase:before { content: "\ea16"; }
.web-icon-github:before { content: "\ea17"; }
.web-icon-google:before { content: "\ea18"; }
.web-icon-hamburger-menu:before { content: "\ea19"; }
.web-icon-light:before { content: "\ea1a"; }
.web-icon-linkedin:before { content: "\ea1b"; }
.web-icon-location:before { content: "\ea1c"; }
.web-icon-logout-left:before { content: "\ea1d"; }
.web-icon-logout-right:before { content: "\ea1e"; }
.web-icon-mailgun:before { content: "\ea1f"; }
.web-icon-message:before { content: "\ea20"; }
.web-icon-microsoft:before { content: "\ea21"; }
.web-icon-minus:before { content: "\ea22"; }
.web-icon-nuxt:before { content: "\ea23"; }
.web-icon-platform:before { content: "\ea24"; }
.web-icon-play:before { content: "\ea25"; }
.web-icon-plus:before { content: "\ea26"; }
.web-icon-product-hunt:before { content: "\ea27"; }
.web-icon-refine:before { content: "\ea28"; }
.web-icon-rest:before { content: "\ea29"; }
.web-icon-search:before { content: "\ea2a"; }
.web-icon-sendgrid:before { content: "\ea2b"; }
.web-icon-star:before { content: "\ea2c"; }
.web-icon-system:before { content: "\ea2d"; }
.web-icon-textmagic:before { content: "\ea2e"; }
.web-icon-twitter:before { content: "\ea2f"; }
.web-icon-vue:before { content: "\ea30"; }
.web-icon-x:before { content: "\ea31"; }
.web-icon-youtube:before { content: "\ea32"; }
.web-icon-daily-dev:before { content: "\ea11"; }
.web-icon-dark:before { content: "\ea12"; }
.web-icon-discord:before { content: "\ea13"; }
.web-icon-divider-vertical:before { content: "\ea14"; }
.web-icon-download:before { content: "\ea15"; }
.web-icon-ext-link:before { content: "\ea16"; }
.web-icon-firebase:before { content: "\ea17"; }
.web-icon-github:before { content: "\ea18"; }
.web-icon-google:before { content: "\ea19"; }
.web-icon-hamburger-menu:before { content: "\ea1a"; }
.web-icon-light:before { content: "\ea1b"; }
.web-icon-linkedin:before { content: "\ea1c"; }
.web-icon-location:before { content: "\ea1d"; }
.web-icon-logout-left:before { content: "\ea1e"; }
.web-icon-logout-right:before { content: "\ea1f"; }
.web-icon-mailgun:before { content: "\ea20"; }
.web-icon-message:before { content: "\ea21"; }
.web-icon-microsoft:before { content: "\ea22"; }
.web-icon-minus:before { content: "\ea23"; }
.web-icon-nuxt:before { content: "\ea24"; }
.web-icon-platform:before { content: "\ea25"; }
.web-icon-play:before { content: "\ea26"; }
.web-icon-plus:before { content: "\ea27"; }
.web-icon-product-hunt:before { content: "\ea28"; }
.web-icon-refine:before { content: "\ea29"; }
.web-icon-rest:before { content: "\ea2a"; }
.web-icon-search:before { content: "\ea2b"; }
.web-icon-sendgrid:before { content: "\ea2c"; }
.web-icon-star:before { content: "\ea2d"; }
.web-icon-system:before { content: "\ea2e"; }
.web-icon-textmagic:before { content: "\ea2f"; }
.web-icon-twitter:before { content: "\ea30"; }
.web-icon-vue:before { content: "\ea31"; }
.web-icon-x:before { content: "\ea32"; }
.web-icon-youtube:before { content: "\ea33"; }

Binary file not shown.

View File

@@ -32,40 +32,41 @@
.web-icon-close:before { content: "\ea0e"; }
.web-icon-command:before { content: "\ea0f"; }
.web-icon-copy:before { content: "\ea10"; }
.web-icon-dark:before { content: "\ea11"; }
.web-icon-discord:before { content: "\ea12"; }
.web-icon-divider-vertical:before { content: "\ea13"; }
.web-icon-download:before { content: "\ea14"; }
.web-icon-ext-link:before { content: "\ea15"; }
.web-icon-firebase:before { content: "\ea16"; }
.web-icon-github:before { content: "\ea17"; }
.web-icon-google:before { content: "\ea18"; }
.web-icon-hamburger-menu:before { content: "\ea19"; }
.web-icon-light:before { content: "\ea1a"; }
.web-icon-linkedin:before { content: "\ea1b"; }
.web-icon-location:before { content: "\ea1c"; }
.web-icon-logout-left:before { content: "\ea1d"; }
.web-icon-logout-right:before { content: "\ea1e"; }
.web-icon-mailgun:before { content: "\ea1f"; }
.web-icon-message:before { content: "\ea20"; }
.web-icon-microsoft:before { content: "\ea21"; }
.web-icon-minus:before { content: "\ea22"; }
.web-icon-nuxt:before { content: "\ea23"; }
.web-icon-platform:before { content: "\ea24"; }
.web-icon-play:before { content: "\ea25"; }
.web-icon-plus:before { content: "\ea26"; }
.web-icon-product-hunt:before { content: "\ea27"; }
.web-icon-refine:before { content: "\ea28"; }
.web-icon-rest:before { content: "\ea29"; }
.web-icon-search:before { content: "\ea2a"; }
.web-icon-sendgrid:before { content: "\ea2b"; }
.web-icon-star:before { content: "\ea2c"; }
.web-icon-system:before { content: "\ea2d"; }
.web-icon-textmagic:before { content: "\ea2e"; }
.web-icon-twitter:before { content: "\ea2f"; }
.web-icon-vue:before { content: "\ea30"; }
.web-icon-x:before { content: "\ea31"; }
.web-icon-youtube:before { content: "\ea32"; }
.web-icon-daily-dev:before { content: "\ea11"; }
.web-icon-dark:before { content: "\ea12"; }
.web-icon-discord:before { content: "\ea13"; }
.web-icon-divider-vertical:before { content: "\ea14"; }
.web-icon-download:before { content: "\ea15"; }
.web-icon-ext-link:before { content: "\ea16"; }
.web-icon-firebase:before { content: "\ea17"; }
.web-icon-github:before { content: "\ea18"; }
.web-icon-google:before { content: "\ea19"; }
.web-icon-hamburger-menu:before { content: "\ea1a"; }
.web-icon-light:before { content: "\ea1b"; }
.web-icon-linkedin:before { content: "\ea1c"; }
.web-icon-location:before { content: "\ea1d"; }
.web-icon-logout-left:before { content: "\ea1e"; }
.web-icon-logout-right:before { content: "\ea1f"; }
.web-icon-mailgun:before { content: "\ea20"; }
.web-icon-message:before { content: "\ea21"; }
.web-icon-microsoft:before { content: "\ea22"; }
.web-icon-minus:before { content: "\ea23"; }
.web-icon-nuxt:before { content: "\ea24"; }
.web-icon-platform:before { content: "\ea25"; }
.web-icon-play:before { content: "\ea26"; }
.web-icon-plus:before { content: "\ea27"; }
.web-icon-product-hunt:before { content: "\ea28"; }
.web-icon-refine:before { content: "\ea29"; }
.web-icon-rest:before { content: "\ea2a"; }
.web-icon-search:before { content: "\ea2b"; }
.web-icon-sendgrid:before { content: "\ea2c"; }
.web-icon-star:before { content: "\ea2d"; }
.web-icon-system:before { content: "\ea2e"; }
.web-icon-textmagic:before { content: "\ea2f"; }
.web-icon-twitter:before { content: "\ea30"; }
.web-icon-vue:before { content: "\ea31"; }
.web-icon-x:before { content: "\ea32"; }
.web-icon-youtube:before { content: "\ea33"; }
$web-icon-apple: "\ea01";
$web-icon-appwrite: "\ea02";
@@ -83,37 +84,38 @@ $web-icon-chevron-up: "\ea0d";
$web-icon-close: "\ea0e";
$web-icon-command: "\ea0f";
$web-icon-copy: "\ea10";
$web-icon-dark: "\ea11";
$web-icon-discord: "\ea12";
$web-icon-divider-vertical: "\ea13";
$web-icon-download: "\ea14";
$web-icon-ext-link: "\ea15";
$web-icon-firebase: "\ea16";
$web-icon-github: "\ea17";
$web-icon-google: "\ea18";
$web-icon-hamburger-menu: "\ea19";
$web-icon-light: "\ea1a";
$web-icon-linkedin: "\ea1b";
$web-icon-location: "\ea1c";
$web-icon-logout-left: "\ea1d";
$web-icon-logout-right: "\ea1e";
$web-icon-mailgun: "\ea1f";
$web-icon-message: "\ea20";
$web-icon-microsoft: "\ea21";
$web-icon-minus: "\ea22";
$web-icon-nuxt: "\ea23";
$web-icon-platform: "\ea24";
$web-icon-play: "\ea25";
$web-icon-plus: "\ea26";
$web-icon-product-hunt: "\ea27";
$web-icon-refine: "\ea28";
$web-icon-rest: "\ea29";
$web-icon-search: "\ea2a";
$web-icon-sendgrid: "\ea2b";
$web-icon-star: "\ea2c";
$web-icon-system: "\ea2d";
$web-icon-textmagic: "\ea2e";
$web-icon-twitter: "\ea2f";
$web-icon-vue: "\ea30";
$web-icon-x: "\ea31";
$web-icon-youtube: "\ea32";
$web-icon-daily-dev: "\ea11";
$web-icon-dark: "\ea12";
$web-icon-discord: "\ea13";
$web-icon-divider-vertical: "\ea14";
$web-icon-download: "\ea15";
$web-icon-ext-link: "\ea16";
$web-icon-firebase: "\ea17";
$web-icon-github: "\ea18";
$web-icon-google: "\ea19";
$web-icon-hamburger-menu: "\ea1a";
$web-icon-light: "\ea1b";
$web-icon-linkedin: "\ea1c";
$web-icon-location: "\ea1d";
$web-icon-logout-left: "\ea1e";
$web-icon-logout-right: "\ea1f";
$web-icon-mailgun: "\ea20";
$web-icon-message: "\ea21";
$web-icon-microsoft: "\ea22";
$web-icon-minus: "\ea23";
$web-icon-nuxt: "\ea24";
$web-icon-platform: "\ea25";
$web-icon-play: "\ea26";
$web-icon-plus: "\ea27";
$web-icon-product-hunt: "\ea28";
$web-icon-refine: "\ea29";
$web-icon-rest: "\ea2a";
$web-icon-search: "\ea2b";
$web-icon-sendgrid: "\ea2c";
$web-icon-star: "\ea2d";
$web-icon-system: "\ea2e";
$web-icon-textmagic: "\ea2f";
$web-icon-twitter: "\ea30";
$web-icon-vue: "\ea31";
$web-icon-x: "\ea32";
$web-icon-youtube: "\ea33";

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 165 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Logo/Dark" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Icon" transform="translate(4.000000, 11.000000)" fill="#151618">
<g id="Secound" opacity="0.56" transform="translate(21.000000, 0.930000)">
<path d="M6.47910463,8.01371418 L2.94663391,4.48124347 L4.71194884,0.95 L10.4515234,6.68957458 C11.1828255,7.42087669 11.1828255,8.60655167 10.4515234,9.33785378 L3.38719562,16.4021816 C2.65589351,17.1334837 1.47021853,17.1334837 0.738916421,16.4021816 C0.00761431424,15.6708795 0.00761431424,14.4852045 0.738916421,13.7539024 L6.47910463,8.01371418 Z" id="Combined-Shape"></path>
</g>
<path d="M21.7402327,0.548323198 C22.4715349,-0.182978908 23.6575166,-0.182672097 24.3888188,0.54863001 L25.7132652,1.87307642 L10.2610836,17.325258 C9.52978147,18.0565601 8.34379968,18.0562533 7.61249757,17.3249512 L6.28805116,16.0005048 L21.7402327,0.548323198 Z M15.1176939,5.40493351 L12.4688011,8.05382633 L8.93633036,4.52135561 L4.52089537,8.9367906 L8.05336609,12.4692613 L6.28805116,16.0005048 L0.54847658,10.2609302 C-0.182825527,9.52962809 -0.182825527,8.34395311 0.54847658,7.612651 L7.61249757,0.54863001 C8.34379968,-0.182672097 9.52978147,-0.182978908 10.2610836,0.548323198 L15.1176939,5.40493351 Z" id="Main"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -16,5 +16,5 @@
<slot />
</video>
{:else}
<img {src} {alt} class={className} />
<img loading="lazy" {src} {alt} class={className} />
{/if}

View File

@@ -40,5 +40,10 @@ export const socials: Array<Social> = [
icon: 'web-icon-youtube',
label: 'YouTube',
link: 'https://www.youtube.com/c/appwrite?sub_confirmation=1'
},
{
icon: 'web-icon-daily-dev',
label: 'Daily.dev',
link: 'https://app.daily.dev/squads/appwrite'
}
];

View File

@@ -1,7 +1,8 @@
import type { AuthorData, PostsData } from "$routes/blog/content";
export const DEFAULT_HOST = 'https://appwrite.io';
export const DEFAULT_DESCRIPTION = 'Appwrite is an open-source platform for building applications at any scale, using your preferred programming languages and tools.';
export const DEFAULT_DESCRIPTION = 'Appwrite is an open-source backend platform offering essential APIs for building web and mobile applications.';
export function buildOpenGraphImage(title: string, description: string): string {
return `https://og.appwrite.global/image.png?title=${encodeURIComponent(
title

View File

@@ -22,7 +22,7 @@
import { Main } from '$lib/layouts';
import { DEFAULT_DESCRIPTION, DEFAULT_HOST } from '$lib/utils/metadata';
import { DEFAULT_HOST } from '$lib/utils/metadata';
import { TITLE_SUFFIX } from '$routes/titles';
@@ -32,11 +32,12 @@
import { getContext, hasContext, setContext } from 'svelte';
export let title: string;
export let description: string;
export let transparentTableCells = false;
const seo = {
let seo = {
title: title + TITLE_SUFFIX,
description: DEFAULT_DESCRIPTION,
description: description,
ogImage: DEFAULT_HOST + '/images/open-graph/website.png',
APP_NAME: 'Appwrite'

View File

@@ -4,14 +4,14 @@
import TocRoot from '$lib/components/TocRoot.svelte';
import { Main } from '$lib/layouts';
import { DEFAULT_DESCRIPTION, DEFAULT_HOST } from '$lib/utils/metadata';
import { DEFAULT_HOST } from '$lib/utils/metadata';
import { TITLE_SUFFIX } from '$routes/titles';
import FooterNav from '../../lib/components/FooterNav.svelte';
import MainFooter from '../../lib/components/MainFooter.svelte';
import Copy from './Copy.svelte';
const title = 'Assets' + TITLE_SUFFIX;
const description = DEFAULT_DESCRIPTION;
const description = 'Resources for presenting the Appwrite brand, ensuring consistency in using our logos, colours, and other brand elements across various platforms and materials.';
const ogImage = DEFAULT_HOST + '/images/open-graph/website.png';
enum Section {

View File

@@ -2,14 +2,14 @@
import { Main } from '$lib/layouts';
import { MainFooter, FooterNav, Article } from '$lib/components';
import { TITLE_SUFFIX } from '$routes/titles.js';
import { DEFAULT_DESCRIPTION, DEFAULT_HOST } from '$lib/utils/metadata';
import { DEFAULT_HOST } from '$lib/utils/metadata';
export let data;
const featured = data.posts.find((post) => post.featured);
const title = 'Blog' + TITLE_SUFFIX;
const description = DEFAULT_DESCRIPTION;
const description = 'Stay updated with the latest product news, insights, and tutorials from the Appwrite team. Discover tips and best practices for hassle-free backend development.';
const ogImage = DEFAULT_HOST + '/images/open-graph/blog.png';
</script>

View File

@@ -1,7 +1,7 @@
---
layout: post
title: How Pink Design helped us improve web accessibility in our products.
description:
description: Appwrites open-source UI library drastically improved our web accessibility.
date: 2022-11-14
cover: /images/pages/homepage/dashboard.png
timeToRead: 3

View File

@@ -0,0 +1,46 @@
---
layout: post
title: Announcing the Appwrite daily.dev Squad
description: Were excited to announce our new daily.dev public Squad, which you, too, can join!
date: 2024-07-23
cover: /images/blog/announcing-appwrite-daily-dot-dev-squad/daily.dev-squad.png
timeToRead: 3
author: laura-du-ry
category: OSS
---
We already share all of our blogs on the [daily.dev](http://daily.dev) platform, and now we also have a moderated Squad. This will make it easier for you to engage with our content and also share your content with the community.
# What is daily.dev?
For those who might not be familiar with it, daily.dev is a platform that curates the latest news, articles, and resources for developers. It's a go-to place to stay updated with what's happening in the world of development, from the latest frameworks and libraries to best practices and industry trends.
# What is a Squad?
A Squad is a specialized group within daily.dev, where you can share knowledge, ask questions, and discuss topics that matter most to you. Think of it as an online group tailored specifically for developers. Squads can be centered around your team, a specific project, a community, or any topic you're passionate about. It's a space to learn, collaborate, and have fun.
# Join the Appwrite Squad
We're excited to invite you to join the Appwrite Squad. Whether you're already a part of the Appwrite community or want to learn more about open source, coding, or Appwrite, our Squad is the perfect place to connect, learn, and share.
By joining our Squad, you'll be able to:
- Stay updated with the latest Appwrite news and updates.
- Find useful engineering resources.
- Engage with the Appwrite team and other developers.
- Share your insights and resources.
- Participate in discussions about development trends, best practices, and more.
# How to join
Joining our Squad is simple:
1. **Visit daily.dev** and create an account if you don't already have one.
2. **Search for "Appwrite Squad"** and click join or follow [**this link**](https://apwr.dev/dailydev).
3. **Start engaging** with posts, share your thoughts, and invite other developers to join us!
We can't wait to see you there and start building a vibrant community together. Let's make the Appwrite Squad a place where knowledge is shared, questions are answered, and connections are made.
[Learn more about Squads](https://docs.daily.dev/docs/squads/creating-your-squad)
[Join us on Discord](https://appwrite.io/discord)

View File

@@ -1,7 +1,7 @@
---
layout: post
title: "Announcing Messaging: Push, Email and SMS directly from your Appwrite backend"
description:
description: You can now send emails, SMS and push notifications with Appwrites easy-to-use APIs.
date: 2024-02-26
cover: /images/blog/messaging-announcement.png
timeToRead: 6

View File

@@ -60,7 +60,7 @@ Learn how to get started with [email in our documentation](/docs/products/messag
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.
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.
```swift
import Appwrite
@@ -72,7 +72,7 @@ let client = Client()
let messaging = Messaging(client)
let message = try await messaging.createSMS(
let message = try await messaging.createSms(
messageId: ID.unique(),
content: "Don't forget your Wednesday meeting at 10am!",
users: ["413da83346a"]

View File

@@ -26,7 +26,7 @@ Despite his unfamiliarity with the tech environment, Appwrite's mission quickly
Dylans favorite aspect of his job is the unity and excitement of Appwrite camps, with Camp 3.0 in New York holding a special place in his heart. Despite the bureaucratic hurdles of bringing together a global team, the satisfaction of a successful camp is unmatched.
![Appwrite team at Camp 3.0](/images/blog/appwrite-decoded-dylan/appwrite-decoded-dylan-camp3.jpg)
![Appwrite team at Camp 3.0](/images/blog/appwrite-decoded-dylan/appwrite-decoded-dylan-camp3.png)
> "Organizing and planning these gatherings is what I thrive on.”
>
@@ -91,7 +91,7 @@ Dylans pro tip for remote work? Treat communication tools as your virtual off
> "It makes everything feel more connected and a lot less isolated."
>
![Appwrite team at Camp 3.0 in New York](/images/blog/appwrite-decoded-dylan/appwrite-decoded-dylan-camp3-1.png)
![Appwrite team at Camp 3.0 in New York](/images/blog/appwrite-decoded-dylan/appwrite-decoded-dylan-camp3.png)
His ascent to operations leader was unexpected but embraced. Initially stepping in as a temporary fix, it wasn't long before the opportunity to lead became permanent, thanks to Eldad's vote of confidence.

View File

@@ -19,7 +19,7 @@ A new product that allows you to send SMS, email, and push notifications through
With just a few lines of backend code, you can set up a full-functioning messaging service under one unified platform.
```ts
messaging.createSMS(
messaging.createSms(
'6541...ea30',
'Thanks for signing up!',
['65415281565570ca1f9c'],

View File

@@ -0,0 +1,194 @@
---
layout: post
title: "How to build a tech stack for a remote startup"
description: 10 tools you need in your remote tech stack.
date: 2024-07-16
cover: /images/blog/how-to-build-remote-tech-stack/cover.png
timeToRead: 5
author: snezhanna
category: startup
---
Building a remote company? Awesome! You've probably read many great stories about the benefits of work-life balance, working from anywhere, and hiring global talent. Or you might come from a 9 to 5 office job and think: never again! Either way, you're here because you now might be wondering, how do I actually communicate, organize, hire, and work fully remotely?
Since day one, Appwrite has been working entirely remotely and across the globe. We've learned a thing or two about what tools work best for us, and we would like to help you get started with your own remote-empowering tech stack.
# How to choose the right tech stack
Before you start looking into your stack, ask yourself what you value most in using tools.
At Appwrite, we appreciate tools that help us work remotely more effectively. We also prefer open-source and privacy-friendly software, though not exclusively.
This list highlights the tech we use to organize our work as an open-source, fully remote, and privacy-focused company.
# 10 tools you need in your remote startup tech stack
## 1. Discord for team communication
![Discord](/images/blog/how-to-build-remote-tech-stack/1.png)
Initially created for gamers, [Discord](https://discord.com/) is designed for real-time communication, which is really important to help remote teams stay connected. We love grouping conversations per team and topic, with additional channels for cross-team collaboration. The “lobby” chat acts as an office space where team members say hi when they log on, have informal conversations, or share gifs — the water cooler talk of remote companies! This helps us feel connected even if our coworkers are online in a different timezone.
Discord is also a favorite of the open source community, with many OSS projects being developed in Discord servers. Appwrite has an active [public server on Discord](https://appwrite.io/discord), and you're welcome to join!
Some Discord pros:
- Ease of use
- Robust features for free
- Serious security features, including 2FA, IP location lock and more
- Versatile communication channels, including audio and video
- Customizable server structure
## 2. Linear for task tracking
![Linear](/images/blog/how-to-build-remote-tech-stack/2.png)
As your remote team and their workloads grow, it becomes crucial to ensure tasks are completed on time, nothing gets overlooked, and no team member feels overwhelmed. At Appwrite, we use [Linear](https://linear.app/) for its straightforward, developer-friendly approach.
Linear began as an issue-tracking software and has evolved into a comprehensive project management platform. It maintains its original concept: each task is an "issue" assigned to a team in 2-week cycles. Issues have an owner, due date, completion stages, and comments. This system makes it easy to track who is responsible for what and distribute workloads evenly among team members. If you've ever managed a project, you know that work expands to fill the time available. By framing issues within 2-week cycles, Linear helps focus efforts and accelerate task completion.
Linear enables us to collaborate effectively across teams. Its intuitive approach is accessible to both developers and non-developers. As a fully remote company, Linear understands the challenges of remote work and offers solutions that truly work.
Some Linear pros:
- Developer-friendly approach
- User-friendly
- 2-week cycles
- Easy task tracking
## 3. Figma for design & collaboration
![Figma](/images/blog/how-to-build-remote-tech-stack/3.png)
You've probably heard of [Figma](http://figma.com) as a design tool. But did you know you can also use it for brainstorming, retrospectives, and collaboration? We love this versatility.
At Appwrite, our design teams use Figma for everything—from product designs and web pages to blog covers and social assets. Meanwhile, the rest of the team can leave comments and collaborate seamlessly.
Figma's whiteboard feature, FigJam, is perfect for brainstorming and real-time collaboration. You can set the topic, start a timer, and let ideas flow freely on a shared whiteboard. This makes brainstorming sessions more cohesive and focused.
Some Figma pros:
- Versatility
- Real-time collaboration
- Easy-to-use
## 4. Notion for databases & collaboration
![Notion](/images/blog/how-to-build-remote-tech-stack/4.png)
Your remote company's documents need a reliable home, and Notion databases are the perfect solution.
Appwrite uses [Notion databases](http://notion.so) as its single source of truth for all crucial information, including the company handbook, team documents, campaign briefs, content databases, and social media calendars.
Notion's collaborative features allow team members to work together in sync and async, making it an excellent choice for a remote setup. This centralization fosters a transparent and cohesive work environment, keeping information easily accessible and up-to-date.
Due to its versatility, Notion might be a bit daunting to get started with — but you can download plenty of free templates to customize your databases to your preference.
Some Notion pros:
- Comprehensive databases
- Async collaboration
- Customizable
- Easy-to-use
## 5. Loom for sharing information remotely
![Loom](/images/blog/how-to-build-remote-tech-stack/5.png)
Organizing a meeting every time you need to demo a tool, explain a new process, or train a new team member can be a real hassle, especially if you're coordinating schedules across different time zones for remote teams. These meetings often turn into a waste of time, especially for repeatable and straightforward tasks.
That's why we're big fans of [Loom](https://www.loom.com/). With Loom, you can record your screen and provide a detailed walkthrough of any process. No more frantic calendar shuffling or missed meetings. Just hit record, explain your thing, and share the video with your team. They can watch it whenever suits them best, whether they're in Tokyo, New York, or anywhere in between. It's handy for maintaining productivity and ensuring everyone stays in the loop, no matter their work hours.
Some Loom pros:
- Async communication
- Easy recording and sharing
- AI tools for a video summary
## 6. Attio for customer relationship management
![Attio](/images/blog/how-to-build-remote-tech-stack/6.png)
As your client base skyrockets through the roof (hopefully!), youll need a way to build relationships with your customers. At Appwrite, we use Attio for CRM.
With [Attio](http://attio.com), we manage our [OSS](https://appwrite.io/blog/post/announcing-the-appwrite-oss-program) and [Startups programs](https://appwrite.io/startups), and keep all partnerships in one place, like creators, events and integrations. Its user-friendly design helps our team track and organize contacts effectively, as well as collaborate on campaigns with ease.
Some Attio pros:
- User-friendly
- Customizable workflows
- Real-time updates
## 7. GitHub team for open source contributions
![GitHub teams](/images/blog/how-to-build-remote-tech-stack/7.png)
GitHub simplifies managing remote teams and permissions. With [GitHub Teams](https://github.com/team), you can organize team members, assign roles, and set specific access levels for repositories.
This approach allows Appwrite to receive open-source contributions from developers around the world in a secure and efficient manner. Developers can suggest changes following our [contributing guidelines](https://github.com/appwrite/appwrite/blob/main/CONTRIBUTING.md), and our teams can quickly review and approve them. This process ensures that every issue undergoes a review before merging, helping to eliminate human error and maintain high-quality standards.
Some Github Team pros:
- Simple role and permission management
- Scalability
- Centralized control
- Activity tracking
## 8. Appwrite for backend
![Appwrite](/images/blog/how-to-build-remote-tech-stack/8.png)
We couldn't end this list without mentioning [Appwrite](https://appwrite.io/). When asked, "Do you use Appwrite to build Appwrite?" the answer is a yes. The team is building Appwrite with the exact same API we let developers use to develop their apps. Our entire backend, including user authentication, databases, and collections, is powered by Appwrite's easy-to-implement APIs.
Appwrite enables you to build a robust backend in half the time and with fewer human resources. By handling complex and time-consuming tasks like authentication and database management, Appwrite lets you focus on the unique features that set your product apart. This also applies to the Appwrite team as we work to improve our products.
Some Appwrite pros:
- Versatile APIs
- Robust and quality features
- Self-hosted or cloud — your choice
- Easy-to-use and understand
# Bonus tools
Now, these tools are not strictly related to remote work. However, they have great privacy features and are integral to our workflows.
## Plausible for analytics
![Plausible](/images/blog/how-to-build-remote-tech-stack/9.png)
[Plausible](http://plausible.io) is a privacy-friendly alternative to Google Analytics, which we opted for as part of [our commitment to data privacy](https://appwrite.io/blog/post/How-to-put-privacy-first). It is an open-source analytics platform with some of the highest [privacy standards](https://plausible.io/privacy). It helps us get demographic and user behavior data from the website and Appwrite Cloud in a privacy-friendly manner.
Some Plausible pros:
- privacy-friendly
- user data is hosted on European servers
- open source
- user-friendly
## [Dub.co](http://Dub.co) for link-building
![Dub.co](/images/blog/how-to-build-remote-tech-stack/10.png)
As a privacy-conscious company, we have stopped using marketing classified pixels such as webpage tags and cookies. As soon as you leave this website, we will lose all information about you.
However, we still like to track the effectiveness of our campaigns. Dub.co, an open-source alternative to Bitly, allows us to create UTM links that track attributions from different campaigns, mediums, sources, and specific content. We can tell whether a visitor is coming from a specific link or not, which helps the growth team see if sponsoring a YouTube video or an event was effective.
Some [dub.co](http://dub.co) pros:
- Open-source
- Straightforward pricing
- Advanced analytics
- Easy-to-use
# Moving forward
Building a remote startup offers many perks, like tapping into the global talent pool, the ability to move fast, and achieve more. But it also comes with its own set of challenges.
Starting with remote-friendly tools in your tech stack will help mitigate some of those challenges, resulting in an agile and smart startup and enabling faster scaling with fewer growing pains.
If youre a startup founder, you might be interested in the [Appwrite Startups Program](https://appwrite.io/startups), which provides free cloud credits and dedicated support to help you build your backend faster. Apply now and create the next big thing with Appwrite.
More resources:
- [How to attract users and contributors to your open-source project](https://appwrite.io/blog/post/how-to-attract-users-to-open-source-project)
- [How to create a privacy-first growth strategy](https://appwrite.io/blog/post/How-to-put-privacy-first)

View File

@@ -66,7 +66,7 @@ const messaging = new sdk.Messaging(client);
.
.
.
const message = await messaging.createSMS(
const message = await messaging.createSms(
sdk.ID.unique(),
'Hello from Appwrite Messaging!',
[smsTopic], // topic to send SMS to

View File

@@ -0,0 +1,264 @@
---
layout: post
title: How to set up Google authentication in React with Appwrite
description: Learn how to set up Google authentication in a React application using Appwrite.
date: 2024-07-19
cover: /images/blog/set-up-google-auth-appwrite-react/cover.png
timeToRead: 9
author: ebenezer-don
category: engineering
featured: false
---
In this article, we'll explore how to set up Google authentication in a React application using Appwrite. Appwrite is an open-source backend solution that provides a wide array of integrated tools and services, covering everything from server-side logic to user management and data storage. While this tutorial focuses on Google OAuth2, Appwrite supports many authentication methods, including [passwordless authentication](https://www.appwrite.io/blog/post/improve-ux-passwordless-auth), magic URL, email OTP, phone number OTP, email/password and various OAuth2 providers.
By the end of this tutorial, you'll have a React app that allows users to log in with their Google account seamlessly. Let's get started!
# Prerequisites
Before diving in, ensure you have the following:
- Basic knowledge of React
- An Appwrite project set up - Learn how to create an Appwrite project [here](/docs/tutorials/react/step-3)
- Access to a Google Cloud account
- Node.js and npm installed on your machine
# Setting up Google OAuth2 in Appwrite
First, we need to configure Appwrite to support Google OAuth2. Log in to your Appwrite console and navigate to the **Auth** section on your left sidebar.
![Appwrite auth page](/images/blog/set-up-google-auth-appwrite-react/auth-page.png)
Click the settings tab and scroll down to the **OAuth2 Providers** section. The OAuth2 providers are arranged alphabetically, so you'll find Google OAuth2 when you scroll to 'G'.
Click it, and a popup will appear with a toggle button and a form to enter your Google OAuth2 credentials.
![Appwrite Google OAuth2 settings](/images/blog/set-up-google-auth-appwrite-react/appwrite-google-oauth.png)
At the bottom of the form, you'll see a "URI" field. Click the copy button beside the URI to save it for later use. This URI is required to set up your Google OAuth client.
Appwrite simplifies OAuth2 integration by supporting multiple providers out of the box, such as Facebook, GitHub, and Twitter. This flexibility makes it easy to extend your authentication methods as your application grows.
# Creating OAuth2 client ID in Google cloud
Let's set up an OAuth2 Client ID in the Google Cloud Console to allow our Appwrite project to communicate with Google for authentication.
Log in to the [Google Cloud Console](https://console.cloud.google.com/). From the projects list, select a project or create a new one. If the APIs & Services page isn't already open, open the console's left-side menu and select APIs & Services. On the left, click Credentials, then “Create credentials,” and select OAuth client ID.
![Google cloud console view](/images/blog/set-up-google-auth-appwrite-react/google-cloud-view.png)
![Google cloud create credentials](/images/blog/set-up-google-auth-appwrite-react/google-cloud-create-credentials.png)
If this is your first time creating a client ID, you need to set up your consent screen. Go to the Google API Console OAuth consent screen page and add the required information like your user type, product name, and support email address.
Click Add Scope, and select the scopes your project uses on the dialog that appears. Sensitive scopes display a lock icon next to the API name. When you're finished adding details to the OAuth consent screen, click Save and Continue. For the purposes of this tutorial, you don't need to submit your app for verification immediately. Google Auth will work for your dev environment even if you skip the verification steps, which include submitting a video demonstration of your app.
Select "Web application" as the application type and add the redirect URI provided by Appwrite. Click Create and save your credentials. Note down the Client ID and Client Secret. You'll need these credentials back in the Appwrite console.
![Google cloud OAuth client ID](/images/blog/set-up-google-auth-appwrite-react/google-credentials-id.png)
# Configuring Appwrite with Google OAuth2 credentials
With your Google Cloud credentials ready, let's complete the setup in the Appwrite console. Return to your Appwrite console and navigate to the Auth section where you enabled Google OAuth2. In the popup, you'll see two fields for "App ID" and "App Secret."
Enter your Google OAuth Client ID into the "App ID" field and your Google OAuth Client Secret into the "App Secret" field. Finally, toggle the "Disabled" button to enable Google OAuth2 authentication and save your changes.
![Appwrite Google OAuth2 credentials](/images/blog/set-up-google-auth-appwrite-react/appwrite-google-oauth-2.png)
You now have Google OAuth2 set up in your Appwrite console! With Appwrite configured and your Google Cloud credentials integrated, let's move on to setting up your React project.
# Setting up your React project
To start, open your terminal and run the following command to create a new React application:
```bash
npx create-react-app appwrite-google-auth
```
Feel free to use any other method you prefer to create your React application, like [Vite](https://vitejs.dev/) for example.
Navigate into your project directory and install the default dependencies:
```bash
cd appwrite-google-auth && npm install
```
Next, install the Appwrite SDK:
```bash
npm install appwrite
```
Create a new file named `appwrite.js` in the `src` directory. Here, we'll initialize the Appwrite client and account service:
```js
// src/appwrite.js
import { Client, Account, OAuthProvider } from 'appwrite'
const client = new Client()
client
.setEndpoint('https://cloud.appwrite.io/v1')// The Appwrite API endpoint
.setProject('project-id')// Your Appwrite project IDexport const account = new Account(client)
export { OAuthProvider }
```
In the `appwrite.js` file, the `Client` object, used to interact with Appwrite services, is initialized with the Appwrite API endpoint and your project ID. The `account` object is created using the client to interact with the Appwrite account service, while the `OAuthProvider` is an enum that contains the OAuth2 providers supported by Appwrite. We are exporting it from this file so you don't have to import both from `appwrite` and `appwrite.js` when you need to use both account and OAuthProvider in a component.
# Create authentication functions
With your React project and Appwrite client set up, you can now create functions to handle login and logout. Create a new file named `auth.js` in the `src` directory. Add the following functions to handle login and logout:
```jsx
// src/auth.js
import { account, OAuthProvider } from './appwrite'
export const loginWithGoogle = async () => {
try {
await account.createOAuth2Session(OAuthProvider.Google)
} catch (error) {
console.error(error)
}
}
export const logoutUser = async () => {
try {
await account.deleteSession('current')
} catch (error) {
console.error(error)
}
}
export const getUser = async () => {
try {
return await account.get()
} catch (error) {
console.error(error)
}
}
```
In the `auth.js` file, we've created three functions: `loginWithGoogle`, `logoutUser` and `getUser`.
- The `loginWithGoogle` function uses the `createOAuth2Session` method to initiate a Google OAuth2 session. The `OAuthProvider` object is imported from the `./appwrite.js` file, which contains the Google OAuth2 provider.
- The `logoutUser` function uses the `deleteSession` method to log out the current user. The `deleteSession` method expects the session ID to be deleted as an argument. In this case, we're passing `'current'` to delete the current session.
- The `getUser` function uses the `get` method to retrieve the current user's account details. This function will be used to display the user's information after they log in or to check if the user is already logged in.
# Set up component for authentication
Next, create a new component named `Auth.js` (this time, with a capital 'A') in the `src` directory. This component will handle the login and logout functionality using the functions we created earlier.
```jsx
// src/Auth.js
import React, { useState, useEffect } from 'react'
import { loginWithGoogle, logoutUser, getUser } from './auth'
const Auth = () => {
const [user, setUser] = useState(null)
useEffect(() => {
const checkUser = async () => {
try {
const userData = await getUser()
setUser(userData)
} catch (error) {
setUser(null)
}
}
checkUser()
}, [])
return (
<div>
{user ? (
<>
<p>Welcome, {user.name}!</p>
<button onClick={logoutUser}>Logout</button>
</>
) : (
<button onClick={loginWithGoogle}>Login with Google</button>
)}
</div>
)
}
export default Auth
```
In the `Auth.js` file, we've created a functional component named `Auth`. This component uses the `useState` and `useEffect` hooks to manage the user's authentication state. The `checkUser` function is called when the component mounts to check if the user is already logged in.
If the user is logged in, the component displays a welcome message with the user's name and a logout button, which triggers the `logoutUser` function when clicked. If the user is not logged in, the component displays a login button that triggers the `loginWithGoogle` function when clicked.
You've now set up the basic structure for Google authentication using Appwrite in your React application. Next, we will integrate and test our authentication flow in the React app.
# Integrate and test Google auth in your React app
With your authentication component set up, it's time to integrate it into your main application and test the Google OAuth2 authentication flow.
## Step 1: Add the `Auth` Component to Your Main Application
Open the `src/App.js` file and add the `Auth` component:
```jsx
// src/App.js
import React from 'react'
import Auth from './Auth'
const App = () => {
return (
<div className="App">
<header className="App-header">
<h1>Appwrite Google Auth Example</h1>
<Auth />
</header>
</div>
)
}
export default App
```
This integration will display the `Auth` component within your main application, providing Google authentication functionality to your users.
## Step 2: Run your React application
To see everything in action, start your React development server by running the following command in your terminal:
```bash
npm start
```
Open your browser and navigate to `http://localhost:3000`. You should see your application with the login button.
## Step 3: Test the authentication flow
### Testing login
1. Click on the "Login with Google" button.
2. You will be redirected to the Google login page.
3. After logging in with your Google account, you should be redirected back to your application.
4. If successful, you should see a welcome message with your Google account name and a "Logout" button.
### Testing logout
1. Click on the "Logout" button.
2. The welcome message should no longer be there, and the "Login with Google" button should show.
## Step 4: Verify user authentication
Every request made through the Appwrite SDK after the user is logged in will include their authentication details automatically. This ensures that actions like reading from or writing to the database will be authenticated without requiring additional credentials.
# Conclusion
You've successfully integrated Google OAuth2 authentication into your React application using Appwrite. With this setup, users can log in with their Google accounts, and you can securely manage their authentication state and data access within your application.
Appwrite supports many OAuth2 providers, including GitHub, Microsoft, Apple, Facebook, and more. This flexibility allows you to easily integrate various authentication options based on your application's needs. Additionally, Appwrite offers a variety of other authentication flows, such as Magic URL, phone authentication, anonymous sessions, team invites, and more. You can explore these options and learn how to implement them in your applications by checking out the [Appwrite Auth Documentation](/docs/products/auth).
Feel free to explore further and build on this foundation to create even more sophisticated and secure applications. If you need any help, don't hesitate to reach out to the Appwrite community on [Discord](https://discord.com/invite/appwrite) for support and guidance.

View File

@@ -72,7 +72,7 @@ Miscellaneous:
- Add tests for scheduled functions
- Remove throw PdoException in Error hook
- Refactor localdevice injection
- Usage sms per country code count
- Usage SMS per country code count
- GetEnv on worker.php
- Feat get env
- Chore: remove compose version

View File

@@ -0,0 +1,14 @@
---
layout: changelog
title: Announcing the Appwrite daily.dev Squad
date: 2024-07-23
cover: /images/changelog/2024-07-23.png
---
Were excited to announce our new daily.dev public Squad, which you, too, can join!
We already share all of our blogs on the [daily.dev](http://daily.dev) platform, and now we also have a moderated Squad. This will make it easier for you to engage with our content and also share your content with the community.
{% arrow_link href="/blog/post/announcing-appwrite-daily-dot-dev-squad" %}
Read the announcement to learn more
{% /arrow_link %}

View File

@@ -9,7 +9,7 @@
<time class="web-caption-400 padded" datetime={entry.date}>{formatDate(entry.date)}</time>
{#if entry.cover}
<a href={entry.href} class="web-media">
<img src={entry.cover} alt="" class="web-u-media-ratio-16-9 u-width-full-line" />
<img src={entry.cover} alt="" loading="lazy" class="web-u-media-ratio-16-9 u-width-full-line" />
</a>
{/if}

View File

@@ -2,7 +2,7 @@
import { goto } from '$app/navigation';
import { FooterNav, MainFooter, PreFooter } from '$lib/components';
import { Main } from '$lib/layouts';
import { DEFAULT_DESCRIPTION, DEFAULT_HOST } from '$lib/utils/metadata';
import { DEFAULT_HOST } from '$lib/utils/metadata';
import { onMount } from 'svelte';
import ChangelogEntry from '../ChangelogEntry.svelte';
import { page } from '$app/stores';
@@ -13,7 +13,7 @@
const seo = {
title: 'Changelog' + TITLE_SUFFIX,
description: DEFAULT_DESCRIPTION,
description: 'Check out our detailed changelog to see what\'s new and what updates have been made to Appwrite Cloud and Self Hosted.',
ogImage: `${DEFAULT_HOST}/images/open-graph/website.png`
};

View File

@@ -52,7 +52,7 @@
import PreFooter from '$lib/components/PreFooter.svelte';
import { GITHUB_STARS } from '$lib/constants';
import { Main } from '$lib/layouts';
import { DEFAULT_DESCRIPTION, DEFAULT_HOST } from '$lib/utils/metadata';
import { DEFAULT_HOST } from '$lib/utils/metadata';
import { TITLE_SUFFIX } from '$routes/titles';
import type { EventCardProps } from './EventCard.svelte';
import EventCard from './EventCard.svelte';
@@ -122,7 +122,7 @@
}
const title = 'Community' + TITLE_SUFFIX;
const description = DEFAULT_DESCRIPTION;
const description = 'Join our vibrant community of developers. Ask questions, contribute solutions, and inspire others to improve the backend development experience.';
const ogImage = DEFAULT_HOST + '/images/open-graph/website.png';
</script>

View File

@@ -36,7 +36,7 @@
<a class="web-grid-articles-item" {href} target="_blank" rel="noopener noreferrer">
<div class="web-grid-articles-item-image">
<img src={cover.src} alt={cover.alt} class="web-u-media-ratio-16-9" />
<img src={cover.src} alt={cover.alt} class="web-u-media-ratio-16-9" loading="lazy" />
</div>
<div class="web-grid-articles-item-content is-no-gap">
<ul class="u-flex u-flex-wrap web-u-list-inline-dot-sep">

View File

@@ -1,6 +1,7 @@
---
layout: policy
title: Cookies Policy
description: Read our cookie policy to understand your choices and manage your preferences.
transparentTableCells: true
---

View File

@@ -2,14 +2,14 @@
import { Carousel } from '$lib/components';
import Technologies from '$lib/components/Technologies.svelte';
import Docs from '$lib/layouts/Docs.svelte';
import { DEFAULT_DESCRIPTION, DEFAULT_HOST } from '$lib/utils/metadata';
import { DEFAULT_HOST } from '$lib/utils/metadata';
import { TITLE_SUFFIX } from '$routes/titles';
import MainFooter from '../../lib/components/MainFooter.svelte';
import CodeCard, { type CodeCardProps } from './CodeCard.svelte';
import Sidebar from './Sidebar.svelte';
const title = 'Docs' + TITLE_SUFFIX;
const description = DEFAULT_DESCRIPTION;
const description = 'Learn how to build like a team of hundreds. Get started with Authentication, Databases, Storage, Functions, and Messaging in your preferred framework.';
const ogImage = DEFAULT_HOST + '/images/open-graph/docs.png';
const tutorials: CodeCardProps[] = [
@@ -245,7 +245,7 @@
Messaging
</h4>
<p class="web-sub-body-400 u-margin-block-start-4">
Send and schedule email, sms, and push notifications.
Send and schedule email, SMS, and push notifications.
</p>
</a>
</li>

View File

@@ -1,7 +1,7 @@
---
layout: article
title: Environment variables
description: Customize the behavior of your self-hosted Appwrite instance to your unique needs. Customize SMTP, sms, functions, S3 adaptor, database, and other behaiors.
description: Customize the behavior of your self-hosted Appwrite instance to your unique needs. Customize SMTP, SMS, functions, S3 adaptor, database, and other behaiors.
---

View File

@@ -50,7 +50,7 @@ Appwrite supports a growing list of SMS providers that you can choose from. Choo
# Environment variables {% #environment-variables %}
You will need to configure these [environment variables](https://example.com/docs/environment-variables#phone) and restart your Appwrite containers before you can use phone authentication.
You will need to configure these [environment variables](https://appwrite.io/docs/environment-variables#phone) and restart your Appwrite containers before you can use phone authentication.
{% info title="URL encode" %}
Ensure the values you insert in the `_APP_SMS_PROVIDER` placeholders are [URL encoded](https://developer.mozilla.org/en-US/docs/Glossary/Percent-encoding) if they contain any non-alphanumeric characters.

View File

@@ -115,7 +115,7 @@ Create an endpoint using your server's framework of choice that accepts a userna
Once you have a session object, you can store it in a cookie. This will allow your users make authenticated requests to the Appwrite API from your server.
Use the `secret` property of the session object as the cookie value. The `expire` property of the session object should be used as the cookie's max age.
Here's an example with Express and PHP, but the same concepts apply to all most frameworks.
Here's an example with Express and PHP, but the same concepts apply to most frameworks.
{% multicode %}
```server-nodejs
import express from 'express';

View File

@@ -52,7 +52,7 @@ While still in beta, Appwrite Cloud has limited support for Cloud runtimes. As w
---
* {% icon icon="python" size="l" /%}
* [Python ML](https://hub.docker.com/r/openruntimes/python-ml)
* `python-ML-3.11`
* `python-ml-3.11`
* x86 / arm64
---
* {% icon icon="dart" size="l" /%}
@@ -151,6 +151,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.16`

View File

@@ -51,7 +51,7 @@
href: '/docs/products/messaging/mailgun'
},
{
label: 'Email with Sendgrid',
label: 'Email with SendGrid',
href: '/docs/products/messaging/sendgrid'
},
{

View File

@@ -887,7 +887,7 @@ client
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
const message = await messaging.createSMS(
const message = await messaging.createSms(
'[MESSAGE_ID]', // messageId
'[CONTENT]', // content
[], // topics (optional)
@@ -911,7 +911,7 @@ client
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
const message = await messaging.createSMS(
const message = await messaging.createSms(
'[MESSAGE_ID]', // messageId
'[CONTENT]', // content
[], // topics (optional)
@@ -937,7 +937,7 @@ $client
$messaging = new Messaging($client);
$result = $messaging->createSMS(
$result = $messaging->createSms(
messageId: '[MESSAGE_ID]',
content: '[CONTENT]',
topics: [], // optional
@@ -1031,7 +1031,7 @@ void main() { // Init SDK
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
Future result = messaging.createSMS(
Future result = messaging.createSms(
messageId: '[MESSAGE_ID]',
content: '[CONTENT]',
topics: [], // optional
@@ -1061,7 +1061,7 @@ Client client = new Client()
Messaging messaging = new Messaging(client);
messaging.createSMS(
messaging.createSms(
"[MESSAGE_ID]", // messageId
"[CONTENT]", // content
listOf(), // topics (optional)
@@ -1091,7 +1091,7 @@ Client client = new Client()
Messaging messaging = new Messaging(client);
messaging.createSMS(
messaging.createSms(
"[MESSAGE_ID]", // messageId
"[CONTENT]", // content
listOf(), // topics (optional)
@@ -1119,7 +1119,7 @@ let client = Client()
let messaging = Messaging(client)
let message = try await messaging.createSMS(
let message = try await messaging.createSms(
messageId: "[MESSAGE_ID]",
content: "[CONTENT]",
topics: [], // optional

View File

@@ -51,10 +51,10 @@ make sure you've configured [a topic](/docs/products/messaging/topics) and [a ta
{% tabsitem #console title="Console" %}
To send a test message, navigate to **Messaging** > **Messages** > {% icon icon="plus" size="m" /%} **Create message** > **SMS**.
{% only_dark %}
![Create an sms message](/images/docs/messaging/messages/dark/create-sms-message.png)
![Create an SMS message](/images/docs/messaging/messages/dark/create-sms-message.png)
{% /only_dark %}
{% only_light %}
![Create an sms message](/images/docs/messaging/messages/create-sms-message.png)
![Create an SMS message](/images/docs/messaging/messages/create-sms-message.png)
{% /only_light %}
Add your message and in the targets step, select one of your test targets. Set the schedule to **Now** and click **Send**.
@@ -80,7 +80,7 @@ client
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
const message = await messaging.createSMS(
const message = await messaging.createSms(
'[MESSAGE_ID]', // messageId
'[CONTENT]', // content
[], // topics (optional)
@@ -104,7 +104,7 @@ client
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
const message = await messaging.createSMS(
const message = await messaging.createSms(
'[MESSAGE_ID]', // messageId
'[CONTENT]', // content
[], // topics (optional)
@@ -130,7 +130,7 @@ $client
$messaging = new Messaging($client);
$result = $messaging->createSMS(
$result = $messaging->createSms(
messageId: '[MESSAGE_ID]',
content: '[CONTENT]',
topics: [], // optional
@@ -224,7 +224,7 @@ void main() { // Init SDK
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
Future result = messaging.createSMS(
Future result = messaging.createSms(
messageId: '[MESSAGE_ID]',
content: '[CONTENT]',
topics: [], // optional
@@ -254,7 +254,7 @@ Client client = new Client()
Messaging messaging = new Messaging(client);
messaging.createSMS(
messaging.createSms(
"[MESSAGE_ID]", // messageId
"[CONTENT]", // content
listOf(), // topics (optional)
@@ -284,7 +284,7 @@ Client client = new Client()
Messaging messaging = new Messaging(client);
messaging.createSMS(
messaging.createSms(
"[MESSAGE_ID]", // messageId
"[CONTENT]", // content
listOf(), // topics (optional)
@@ -312,7 +312,7 @@ let client = Client()
let messaging = Messaging(client)
let message = try await messaging.createSMS(
let message = try await messaging.createSms(
messageId: "[MESSAGE_ID]",
content: "[CONTENT]",
topics: [], // optional

View File

@@ -3,8 +3,8 @@ layout: article
title: Send SMS messages
description: Send SMS messages to your users using Appwrite Messaging.
---
You can send custom sms messages to your app's users using Appwrite Messaging and a connected SMTP service.
This guide takes you through the implementation path of adding sms messaging to your app.
You can send custom SMS messages to your app's users using Appwrite Messaging and a connected SMTP service.
This guide takes you through the implementation path of adding SMS messaging to your app.
# Add a provider {% #add-a-provider %}
Appwrite supports [Twilio](/docs/products/messaging/twilio/),
@@ -463,7 +463,7 @@ let topic = try await messaging.createTopic(
# Send SMS messages {% #send-sms %}
You can send SMS messages using a Server SDK.
To send an SMS messages immediately, you can call the `createSMS` endpoint without passing either the `draft` or `scheduledAt` parameters.
To send an SMS messages immediately, you can call the `createSms` endpoint without passing either the `draft` or `scheduledAt` parameters.
{% multicode %}
```server-nodejs
@@ -477,7 +477,7 @@ const client = new sdk.Client()
const messaging = new sdk.Messaging(client);
const message = await messaging.createSMS(
const message = await messaging.createSms(
'[MESSAGE_ID]', // messageId
'[CONTENT]', // content
[], // topics (optional)
@@ -497,7 +497,7 @@ const client = new sdk.Client()
const messaging = new sdk.Messaging(client);
const message = await messaging.createSMS(
const message = await messaging.createSms(
'[MESSAGE_ID]', // messageId
'[CONTENT]', // content
[], // topics (optional)
@@ -522,7 +522,7 @@ $client
$messaging = new Messaging($client);
$result = $messaging->createSMS(
$result = $messaging->createSms(
messageId: '[MESSAGE_ID]',
content: '[CONTENT]',
topics: [], // optional
@@ -608,7 +608,7 @@ Client client = Client();
Messaging messaging = Messaging(client);
Message message result = await messaging.createSMS(
Message message result = await messaging.createSms(
messageId: '[MESSAGE_ID]',
content: '[CONTENT]',
topics: [], // optional
@@ -630,7 +630,7 @@ val client = Client()
val messaging = Messaging(client)
val message - await messaging.createSMS(
val message - await messaging.createSms(
messageId = "[MESSAGE_ID]",
content = "[CONTENT]",
topics = listOf(),
@@ -652,7 +652,7 @@ Client client = new Client()
Messaging messaging = new Messaging(client);
messaging.createSMS(
messaging.createSms(
"[MESSAGE_ID]", // messageId
"[CONTENT]", // content
listOf(), // topics (optional)
@@ -680,7 +680,7 @@ let client = Client()
let messaging = Messaging(client)
let message = try await messaging.createSMS(
let message = try await messaging.createSms(
messageId: "[MESSAGE_ID]",
content: "[CONTENT]",
topics: [], // optional
@@ -693,7 +693,7 @@ let message = try await messaging.createSMS(
{% /multicode %}
# Schedule SMS message {% #schedule-sms %}
To send an scheduled SMS message, you can call the `createSMS` endpoint with `scheduledAt` as a ISO 8601 date time string for the scheduled time.
To send an scheduled SMS message, you can call the `createSms` endpoint with `scheduledAt` as a ISO 8601 date time string for the scheduled time.
{% multicode %}
```server-nodejs
const sdk = require('node-appwrite');
@@ -706,7 +706,7 @@ const client = new sdk.Client()
const messaging = new sdk.Messaging(client);
const message = await messaging.createSMS(
const message = await messaging.createSms(
'[MESSAGE_ID]', // messageId
'[CONTENT]', // content
[], // topics (optional)
@@ -726,7 +726,7 @@ const client = new sdk.Client()
const messaging = new sdk.Messaging(client);
const message = await messaging.createSMS(
const message = await messaging.createSms(
'[MESSAGE_ID]', // messageId
'[CONTENT]', // content
[], // topics (optional)
@@ -751,7 +751,7 @@ $client
$messaging = new Messaging($client);
$result = $messaging->createSMS(
$result = $messaging->createSms(
messageId: '[MESSAGE_ID]',
content: '[CONTENT]',
topics: [], // optional
@@ -837,7 +837,7 @@ Client client = Client();
Messaging messaging = Messaging(client);
Message message result = await messaging.createSMS(
Message message result = await messaging.createSms(
messageId: '[MESSAGE_ID]',
content: '[CONTENT]',
topics: [], // optional
@@ -859,7 +859,7 @@ val client = Client()
val messaging = Messaging(client)
val message - await messaging.createSMS(
val message - await messaging.createSms(
messageId = "[MESSAGE_ID]",
content = "[CONTENT]",
topics = listOf(),
@@ -881,7 +881,7 @@ Client client = new Client()
Messaging messaging = new Messaging(client);
messaging.createSMS(
messaging.createSms(
"[MESSAGE_ID]", // messageId
"[CONTENT]", // content
listOf(), // topics (optional)
@@ -909,7 +909,7 @@ let client = Client()
let messaging = Messaging(client)
let message = try await messaging.createSMS(
let message = try await messaging.createSms(
messageId: "[MESSAGE_ID]",
content: "[CONTENT]",
topics: [], // optional

View File

@@ -1,16 +1,16 @@
---
layout: article
title: Sendgrid
description: Send emails to your Appwrite users using Sendgrid and Appwrite Messaging.
title: SendGrid
description: Send emails to your Appwrite users using SendGrid and Appwrite Messaging.
back: /docs/
---
Sendgrid lets you send customized email messages to your users.
SendGrid lets you send customized email messages to your users.
These emails can be sent immediately or scheduled.
You can send emails for purposes like reminders, promotions, announcements, and even custom authentication flows.
{% section #add-provider step=1 title="Add provider" %}
To add Sendgrid as a provider, navigate to **Messaging** > **Providers** > {% icon icon="plus" size="m" /%} **Add provider** > **Email**.
To add SendGrid as a provider, navigate to **Messaging** > **Providers** > {% icon icon="plus" size="m" /%} **Add provider** > **Email**.
{% only_dark %}
![Add a SMTP provider](/images/docs/messaging/providers/sendgrid/dark/add-sendgrid.png)
{% /only_dark %}
@@ -18,12 +18,12 @@ To add Sendgrid as a provider, navigate to **Messaging** > **Providers** > {% ic
![Add a SMTP provider](/images/docs/messaging/providers/sendgrid/add-sendgrid.png)
{% /only_light %}
Give your provider a name > choose **Sendgrid** > click **Save and continue**.
Give your provider a name > choose **SendGrid** > 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 Sendgrid dashboard to connect your Appwrite project.
In the **Configure** step, you will need to provide details from your SendGrid dashboard to connect your Appwrite project.
{% only_dark %}
![Configure SMTP provider](/images/docs/messaging/providers/sendgrid/dark/configure-sendgrid.png)
@@ -31,27 +31,23 @@ In the **Configure** step, you will need to provide details from your Sendgrid d
{% only_light %}
![Configure SMTP provider](/images/docs/messaging/providers/sendgrid/configure-sendgrid.png)
{% /only_light %}
You will need to provide the following information from your **Sendgrid dashboard**.
You will need to provide the following information from your **SendGrid dashboard**.
{% table %}
* Field name
*
---
* API key
* Head to Profile -> API Security -> Add new key.
---
* Domain
* Head to Sending -> Domains -> Add new domain.
Follow [Mailgun's instructions](https://help.mailgun.com/hc/en-us/articles/360026833053-Domain-Verification-Walkthrough) to verify the domain name.
* Head to Settings -> API Keys -> Create API Key.
---
* Sender email
* The provider sends emails from this sender email. The sender email needs to be an email under the configured domain.
* The provider sends emails from this sender email. The sender email must either be an email under an [authenticated domain](https://www.twilio.com/docs/sendgrid/ui/account-and-settings/how-to-set-up-domain-authentication) or a [verified sender identity](https://www.twilio.com/docs/sendgrid/ui/sending-email/sender-verification).
---
* Sender name
* The sender name that appears in the emails sent from this provider.
---
* Reply-to email
* The reply-to email that appears in the emails sent from this provider. The reply-to email needs to be an email under the configured domain.
* The reply-to email that appears in the emails sent from this provider. The reply-to email must either be an email under an authenticated domain or a verified sender identity.
---
* Reply-to name
* The reply-to name that appears in the emails sent from this provider.
@@ -95,7 +91,7 @@ client
.setKey('<API_KEY>') // Your secret API key
;
const message - await messaging.createEmail('<MESSAGE_ID>', '<SUBJECT>', '<CONTENT>');
const message = await messaging.createEmail('<MESSAGE_ID>', '<SUBJECT>', '<CONTENT>');
```
```deno
import * as sdk from "https://deno.land/x/appwrite/mod.ts";
@@ -305,12 +301,10 @@ client
.setKey('<YOUR_API_KEY>') // Your secret API key
;
const provider = await messaging.updateMailgunProvider(
const provider = await messaging.updateSendgridProvider(
'[PROVIDER_ID]', // providerId
'[NAME]', // name (optional)
'[API_KEY]', // apiKey (optional)
'[DOMAIN]', // domain (optional)
false, // isEuRegion (optional)
false, // enabled (optional)
'[FROM_NAME]', // fromName (optional)
'email@example.com', // fromEmail (optional)
@@ -332,12 +326,10 @@ client
.setKey('<YOUR_API_KEY>') // Your secret API key
;
const provider = await messaging.updateMailgunProvider(
const provider = await messaging.updateSendgridProvider(
'[PROVIDER_ID]', // providerId
'[NAME]', // name (optional)
'[API_KEY]', // apiKey (optional)
'[DOMAIN]', // domain (optional)
false, // isEuRegion (optional)
false, // enabled (optional)
'[FROM_NAME]', // fromName (optional)
'email@example.com', // fromEmail (optional)
@@ -361,12 +353,10 @@ $client
$messaging = new Messaging($client);
$result = $messaging->updateMailgunProvider(
$result = $messaging->updateSendgridProvider(
providerId: '[PROVIDER_ID]',
name: '[NAME]', // optional
apiKey: '[API_KEY]', // optional
domain: '[DOMAIN]', // optional
isEuRegion: false, // optional
enabled: false, // optional
fromName: '[FROM_NAME]', // optional
fromEmail: 'email@example.com', // optional
@@ -388,12 +378,10 @@ client = Client()
messaging = Messaging(client)
result = messaging.update_mailgun_provider(
result = messaging.update_sendgrid_provider(
provider_id = '[PROVIDER_ID]',
name = '[NAME]', # optional
api_key = '[API_KEY]', # optional
domain = '[DOMAIN]', # optional
is_eu_region = False, # optional
enabled = False, # optional
from_name = '[FROM_NAME]', # optional
from_email = 'email@example.com', # optional
@@ -413,12 +401,10 @@ client = Client.new
messaging = Messaging.new(client)
response = messaging.update_mailgun_provider(
response = messaging.update_sendgrid_provider(
provider_id: '[PROVIDER_ID]',
name: '[NAME]', # optional
api_key: '[API_KEY]', # optional
domain: '[DOMAIN]', # optional
is_eu_region: false, # optional
enabled: false, # optional
from_name: '[FROM_NAME]', # optional
from_email: 'email@example.com', # optional
@@ -440,12 +426,10 @@ var client = new Client()
var messaging = new Messaging(client);
Provider result = await messaging.UpdateMailgunProvider(
Provider result = await messaging.UpdateSendgridProvider(
providerId: "[PROVIDER_ID]"
name: "[NAME]" // optional
apiKey: "[API_KEY]" // optional
domain: "[DOMAIN]" // optional
isEuRegion: false // optional
enabled: false // optional
fromName: "[FROM_NAME]" // optional
fromEmail: "email@example.com" // optional
@@ -467,12 +451,10 @@ void main() { // Init SDK
.setKey('<YOUR_API_KEY>') // Your secret API key
;
Future result = messaging.updateMailgunProvider(
Future result = messaging.updateSendgridProvider(
providerId: '[PROVIDER_ID]',
name: '[NAME]', // optional
apiKey: '[API_KEY]', // optional
domain: '[DOMAIN]', // optional
isEuRegion: false, // optional
enabled: false, // optional
fromName: '[FROM_NAME]', // optional
fromEmail: 'email@example.com', // optional
@@ -500,12 +482,10 @@ Client client = new Client()
Messaging messaging = new Messaging(client);
messaging.updateMailgunProvider(
messaging.updateSendgridProvider(
"[PROVIDER_ID]", // providerId
"[NAME]", // name (optional)
"[API_KEY]", // apiKey (optional)
"[DOMAIN]", // domain (optional)
false, // isEuRegion (optional)
false, // enabled (optional)
"[FROM_NAME]", // fromName (optional)
"email@example.com", // fromEmail (optional)
@@ -533,12 +513,10 @@ Client client = new Client()
Messaging messaging = new Messaging(client);
messaging.updateMailgunProvider(
messaging.updateSendgridProvider(
"[PROVIDER_ID]", // providerId
"[NAME]", // name (optional)
"[API_KEY]", // apiKey (optional)
"[DOMAIN]", // domain (optional)
false, // isEuRegion (optional)
false, // enabled (optional)
"[FROM_NAME]", // fromName (optional)
"email@example.com", // fromEmail (optional)
@@ -564,12 +542,10 @@ let client = Client()
let messaging = Messaging(client)
let provider = try await messaging.updateMailgunProvider(
let provider = try await messaging.updateSendgridProvider(
providerId: "[PROVIDER_ID]",
name: "[NAME]", // optional
apiKey: "[API_KEY]", // optional
domain: "[DOMAIN]", // optional
isEuRegion: xfalse, // optional
enabled: xfalse, // optional
fromName: "[FROM_NAME]", // optional
fromEmail: "email@example.com", // optional

View File

@@ -79,7 +79,7 @@ client
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
const messaging = await messaging.createSMS(
const messaging = await messaging.createSms(
'[MESSAGE_ID]', // messageId
'[CONTENT]', // content
[], // topics (optional)
@@ -103,7 +103,7 @@ client
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
const messaging = await messaging.createSMS(
const messaging = await messaging.createSms(
'[MESSAGE_ID]', // messageId
'[CONTENT]', // content
[], // topics (optional)
@@ -129,7 +129,7 @@ $client
$messaging = new Messaging($client);
$result = $messaging->createSMS(
$result = $messaging->createSms(
messageId: '[MESSAGE_ID]',
content: '[CONTENT]',
topics: [], // optional
@@ -223,7 +223,7 @@ void main() { // Init SDK
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
Future result = messaging.createSMS(
Future result = messaging.createSms(
messageId: '[MESSAGE_ID]',
content: '[CONTENT]',
topics: [], // optional
@@ -253,7 +253,7 @@ Client client = new Client()
Messaging messaging = new Messaging(client);
messaging.createSMS(
messaging.createSms(
"[MESSAGE_ID]", // messageId
"[CONTENT]", // content
listOf(), // topics (optional)
@@ -283,7 +283,7 @@ Client client = new Client()
Messaging messaging = new Messaging(client);
messaging.createSMS(
messaging.createSms(
"[MESSAGE_ID]", // messageId
"[CONTENT]", // content
listOf(), // topics (optional)
@@ -311,7 +311,7 @@ let client = Client()
let messaging = Messaging(client)
let message = try await messaging.createSMS(
let message = try await messaging.createSms(
messageId: "[MESSAGE_ID]",
content: "[CONTENT]",
topics: [], // optional

View File

@@ -51,10 +51,10 @@ make sure you've configured [a topic](/docs/products/messaging/topics) and [a ta
{% tabsitem #console title="Console" %}
To send a test message, navigate to **Messaging** > **Messages** > {% icon icon="plus" size="m" /%} **Create message** > **SMS**.
{% only_dark %}
![Create an sms message](/images/docs/messaging/messages/dark/create-sms-message.png)
![Create an SMS message](/images/docs/messaging/messages/dark/create-sms-message.png)
{% /only_dark %}
{% only_light %}
![Create an sms message](/images/docs/messaging/messages/create-sms-message.png)
![Create an SMS message](/images/docs/messaging/messages/create-sms-message.png)
{% /only_light %}
Add your message and in the targets step, select one of your test targets. Set the schedule to **Now** and click **Send**.
@@ -79,7 +79,7 @@ client
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
const messaging = await messaging.createSMS(
const messaging = await messaging.createSms(
'[MESSAGE_ID]', // messageId
'[CONTENT]', // content
[], // topics (optional)
@@ -103,7 +103,7 @@ client
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
const messaging = await messaging.createSMS(
const messaging = await messaging.createSms(
'[MESSAGE_ID]', // messageId
'[CONTENT]', // content
[], // topics (optional)
@@ -129,7 +129,7 @@ $client
$messaging = new Messaging($client);
$result = $messaging->createSMS(
$result = $messaging->createSms(
messageId: '[MESSAGE_ID]',
content: '[CONTENT]',
topics: [], // optional
@@ -223,7 +223,7 @@ void main() { // Init SDK
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
Future result = messaging.createSMS(
Future result = messaging.createSms(
messageId: '[MESSAGE_ID]',
content: '[CONTENT]',
topics: [], // optional
@@ -253,7 +253,7 @@ Client client = new Client()
Messaging messaging = new Messaging(client);
messaging.createSMS(
messaging.createSms(
"[MESSAGE_ID]", // messageId
"[CONTENT]", // content
listOf(), // topics (optional)
@@ -283,7 +283,7 @@ Client client = new Client()
Messaging messaging = new Messaging(client);
messaging.createSMS(
messaging.createSms(
"[MESSAGE_ID]", // messageId
"[CONTENT]", // content
listOf(), // topics (optional)
@@ -311,7 +311,7 @@ let client = Client()
let messaging = Messaging(client)
let message = try await messaging.createSMS(
let message = try await messaging.createSms(
messageId: "[MESSAGE_ID]",
content: "[CONTENT]",
topics: [], // optional

View File

@@ -52,10 +52,10 @@ make sure you've configured [a topic](/docs/products/messaging/topics) and [a ta
{% tabsitem #console title="Console" %}
To send a test message, navigate to **Messaging** > **Messages** > {% icon icon="plus" size="m" /%} **Create message** > **SMS**.
{% only_dark %}
![Create an sms message](/images/docs/messaging/messages/dark/create-sms-message.png)
![Create an SMS message](/images/docs/messaging/messages/dark/create-sms-message.png)
{% /only_dark %}
{% only_light %}
![Create an sms message](/images/docs/messaging/messages/create-sms-message.png)
![Create an SMS message](/images/docs/messaging/messages/create-sms-message.png)
{% /only_light %}
Add your message and in the targets step, select one of your test targets. Set the schedule to **Now** and click **Send**.
@@ -81,7 +81,7 @@ client
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
const message = await messaging.createSMS(
const message = await messaging.createSms(
'[MESSAGE_ID]', // messageId
'[CONTENT]', // content
[], // topics (optional)
@@ -105,7 +105,7 @@ client
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
const message = await messaging.createSMS(
const message = await messaging.createSms(
'[MESSAGE_ID]', // messageId
'[CONTENT]', // content
[], // topics (optional)
@@ -131,7 +131,7 @@ $client
$messaging = new Messaging($client);
$result = $messaging->createSMS(
$result = $messaging->createSms(
messageId: '[MESSAGE_ID]',
content: '[CONTENT]',
topics: [], // optional
@@ -225,7 +225,7 @@ void main() { // Init SDK
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
Future result = messaging.createSMS(
Future result = messaging.createSms(
messageId: '[MESSAGE_ID]',
content: '[CONTENT]',
topics: [], // optional
@@ -255,7 +255,7 @@ Client client = new Client()
Messaging messaging = new Messaging(client);
messaging.createSMS(
messaging.createSms(
"[MESSAGE_ID]", // messageId
"[CONTENT]", // content
listOf(), // topics (optional)
@@ -285,7 +285,7 @@ Client client = new Client()
Messaging messaging = new Messaging(client);
messaging.createSMS(
messaging.createSms(
"[MESSAGE_ID]", // messageId
"[CONTENT]", // content
listOf(), // topics (optional)
@@ -313,7 +313,7 @@ let client = Client()
let messaging = Messaging(client)
let message = try await messaging.createSMS(
let message = try await messaging.createSms(
messageId: "[MESSAGE_ID]",
content: "[CONTENT]",
topics: [], // optional

View File

@@ -53,10 +53,10 @@ make sure you've configured [a topic](/docs/products/messaging/topics) and [a ta
{% tabsitem #console title="Console" %}
To send a test message, navigate to **Messaging** > **Messages** > {% icon icon="plus" size="m" /%} **Create message** > **SMS**.
{% only_dark %}
![Create an sms message](/images/docs/messaging/messages/dark/create-sms-message.png)
![Create an SMS message](/images/docs/messaging/messages/dark/create-sms-message.png)
{% /only_dark %}
{% only_light %}
![Create an sms message](/images/docs/messaging/messages/create-sms-message.png)
![Create an SMS message](/images/docs/messaging/messages/create-sms-message.png)
{% /only_light %}
Add your message and in the targets step, select one of your test targets. Set the schedule to **Now** and click **Send**.
@@ -81,7 +81,7 @@ client
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
const message = await messaging.createSMS(
const message = await messaging.createSms(
'[MESSAGE_ID]', // messageId
'[CONTENT]', // content
[], // topics (optional)
@@ -105,7 +105,7 @@ client
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
const message = await messaging.createSMS(
const message = await messaging.createSms(
'[MESSAGE_ID]', // messageId
'[CONTENT]', // content
[], // topics (optional)
@@ -131,7 +131,7 @@ $client
$messaging = new Messaging($client);
$result = $messaging->createSMS(
$result = $messaging->createSms(
messageId: '[MESSAGE_ID]',
content: '[CONTENT]',
topics: [], // optional
@@ -225,7 +225,7 @@ void main() { // Init SDK
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
Future result = messaging.createSMS(
Future result = messaging.createSms(
messageId: '[MESSAGE_ID]',
content: '[CONTENT]',
topics: [], // optional
@@ -255,7 +255,7 @@ Client client = new Client()
Messaging messaging = new Messaging(client);
messaging.createSMS(
messaging.createSms(
"[MESSAGE_ID]", // messageId
"[CONTENT]", // content
listOf(), // topics (optional)
@@ -285,7 +285,7 @@ Client client = new Client()
Messaging messaging = new Messaging(client);
messaging.createSMS(
messaging.createSms(
"[MESSAGE_ID]", // messageId
"[CONTENT]", // content
listOf(), // topics (optional)
@@ -313,7 +313,7 @@ let client = Client()
let messaging = Messaging(client)
let message = try await messaging.createSMS(
let message = try await messaging.createSms(
messageId: "[MESSAGE_ID]",
content: "[CONTENT]",
topics: [], // optional

View File

@@ -166,7 +166,7 @@
];
const title = 'Quick starts' + DOCS_TITLE_SUFFIX;
const description = '';
const description = 'Get started with your favorite framework and language in just a few clicks.';
const ogImage = DEFAULT_HOST + '/images/open-graph/docs.png';
</script>

View File

@@ -160,6 +160,7 @@ class ViewModel: ObservableObject {
struct ContentView: View {
@ObservedObject var viewModel = ViewModel()
let appwrite = Appwrite()
var body: some View {
VStack {
@@ -173,7 +174,7 @@ struct ContentView: View {
)
Button(
action: { Task {
try await Appwrite.onRegister(
try await appwrite.onRegister(
viewModel.email,
viewModel.password
)
@@ -184,7 +185,7 @@ struct ContentView: View {
)
Button(
action: { Task {
try! await Appwrite.onLogin(
try! await appwrite.onLogin(
viewModel.email,
viewModel.password
)

View File

@@ -1,10 +1,10 @@
<script lang="ts">
import { MainFooter } from '$lib/components';
import { DEFAULT_DESCRIPTION, DEFAULT_HOST } from '$lib/utils/metadata';
import { DEFAULT_HOST } from '$lib/utils/metadata';
import { DOCS_TITLE_SUFFIX } from '$routes/titles';
const title = 'Tutorials' + DOCS_TITLE_SUFFIX;
const description = DEFAULT_DESCRIPTION;
const description = 'Follow a simple tutorial to get started with Appwrite in your preferred framework quickly and easily.';
const ogImage = DEFAULT_HOST + '/images/open-graph/docs.png';
export let data;

View File

@@ -1,6 +1,6 @@
<script lang="ts">
import { FooterNav, MainFooter, PreFooter } from '$lib/components';
import { DEFAULT_DESCRIPTION, DEFAULT_HOST } from '$lib/utils/metadata';
import { DEFAULT_HOST } from '$lib/utils/metadata';
import { Main } from '$lib/layouts';
import { TITLE_SUFFIX } from '$routes/titles';
@@ -9,7 +9,7 @@
import BG from './bg.png?enhanced';
const title = 'Pricing' + TITLE_SUFFIX;
const description = DEFAULT_DESCRIPTION;
const description = 'Explore our straightforward pricing plans that scale with your project.';
const ogImage = DEFAULT_HOST + '/images/open-graph/website.png';
</script>

View File

@@ -1,5 +1,6 @@
---
layout: policy
description: Understand how we collect, use, and protect your personal information.
title: Privacy Policy
---
This privacy policy (“Privacy Policy”) governs how we, Appwrite Code Ltd. (together, “Appwrite” “we”, “our” or “us”) use, collect and store Personal Data we collect or receive from or about you (“you”) such as in the following use cases:
@@ -329,7 +330,7 @@ How we protect and retain your personal data
We have implemented appropriate technical, organizational and security measures designed to protect your Personal Data. However, please note that we cannot guarantee that the information will not be compromised as a result of unauthorized penetration to our servers. As the security of information depends in part on the security of the computer, device or network you use to communicate with us and the security you use to protect your user IDs and passwords, please make sure to take appropriate measures to protect this information.
{% count_title title="Retention of your personal data" / %}
Your Personal Data will be stored until we delete the record and we proactively delete it or you send a valid deletion request, please note that in some circumstances we may store your Personal Data for longer periods of time, for example (i) where we are required to do so in accordance with legal, regulatory, tax or accounting requirements, or (ii) for us to have an accurate record of your dealings with us in the event of any complaints or challenges, or (iii) if we reasonably believe there is a prospect of litigation relating to your Personal Data or dealings. Regaioention of cookies, you can read more in our cookie policy [https://appwrite.io/policy/cookies](https://appwrite.io/policy/cookies).
Your Personal Data will be stored until we delete the record and we proactively delete it or you send a valid deletion request, please note that in some circumstances we may store your Personal Data for longer periods of time, for example (i) where we are required to do so in accordance with legal, regulatory, tax or accounting requirements, or (ii) for us to have an accurate record of your dealings with us in the event of any complaints or challenges, or (iii) if we reasonably believe there is a prospect of litigation relating to your Personal Data or dealings. Regarding retention of cookies, you can [read more in our cookie policy](https://appwrite.io/policy/cookies).
{% /count_section %}
{% count_section %}

View File

@@ -8,6 +8,7 @@
import Send from './(components)/Send.svelte';
import Target from './(components)/Target.svelte';
import MultiCodeContextless from './(components)/MultiCodeContextless.svelte';
import { Platform } from '$lib/utils/references';
const title = 'Messaging' + TITLE_SUFFIX;
const description = DEFAULT_DESCRIPTION;
@@ -15,7 +16,7 @@
const codeTopic = [
{
language: 'js',
language: 'client-web',
content: `import { Account, Messaging, ID } from "appwrite"
// Fetch target ID
@@ -32,7 +33,7 @@ await messaging.createSubscriber(
)`
},
{
language: 'dart',
language: 'client-flutter',
content: `import 'package:appwrite/appwrite.dart';
// Fetch target ID
@@ -49,7 +50,7 @@ await messaging.createSubscriber(
);`
},
{
language: 'kotlin',
language: 'client-android-kotlin',
content: `import io.appwrite.services.Account
import io.appwrite.services.Messaging
import io.appwrite.ID
@@ -68,7 +69,7 @@ messaging.createSubscriber(
)`
},
{
language: 'swift',
language: 'client-apple',
content: `import Appwrite
// Fetch target ID
@@ -88,24 +89,11 @@ try await messaging.createSubscriber(
const codeMessage = [
{
language: 'js',
language: "server-nodejs",
platform: 'Node.js',
content: `import { Messaging, ID } from "node-appwrite"
const messaging = Messaging(client);
await messaging.createPush(
ID.unique(), // Message ID
'Breaking update', // Push title
'Hello, world!', // Push body
['news', 'sport'], // Topic IDs
);`
},
{
language: 'ts',
platform: 'Deno',
content: `import { Messaging, ID } from "https://deno.land/x/appwrite/mod.ts";
const messaging = new Messaging(client);
await messaging.createPush(
ID.unique(), // Message ID
'Breaking update', // Push title
@@ -279,13 +267,13 @@ messaging.create_email(
directly to your users.
</p>
<div class="u-flex u-items-center u-gap-8 u-margin-block-start-32 hero-buttons">
<a class="web-button" href="https://cloud.appwrite.io" target="_blank"
<a class="web-button" href="https://cloud.appwrite.io"
>Get started</a
>
<a
class="web-button is-secondary"
href="https://appwrite.io/docs/products/messaging"
target="_blank">Documentation</a
href="/docs/products/messaging"
>Documentation</a
>
</div>
</div>
@@ -333,8 +321,6 @@ messaging.create_email(
<a
class="web-interactive-tag"
href="/docs/products/messaging/fcm"
target="_blank"
rel="noopener noreferrer"
>
<span class="web-icon-firebase" aria-hidden="true" />
<span class="text">FCM</span>
@@ -344,8 +330,6 @@ messaging.create_email(
<a
class="web-interactive-tag"
href="/docs/products/messaging/apns"
target="_blank"
rel="noopener noreferrer"
>
<span class="web-icon-apple" aria-hidden="true" />
<span class="text">APNS</span>
@@ -370,8 +354,6 @@ messaging.create_email(
<a
class="web-interactive-tag"
href="/docs/products/messaging/mailgun"
target="_blank"
rel="noopener noreferrer"
>
<span class="web-icon-mailgun" aria-hidden="true" />
<span class="text">Mailgun</span>
@@ -381,8 +363,6 @@ messaging.create_email(
<a
class="web-interactive-tag"
href="/docs/products/messaging/sendgrid"
target="_blank"
rel="noopener noreferrer"
>
<span class="web-icon-sendgrid" aria-hidden="true" />
<span class="text">SendGrid</span>
@@ -406,8 +386,6 @@ messaging.create_email(
<a
class="web-interactive-tag"
href="/docs/products/messaging/twilio"
target="_blank"
rel="noopener noreferrer"
>
<span class="icon-twilio" aria-hidden="true" />
<span class="text">Twilio</span>
@@ -417,8 +395,6 @@ messaging.create_email(
<a
class="web-interactive-tag"
href="/docs/products/messaging/vonage"
target="_blank"
rel="noopener noreferrer"
>
<span class="icon-vonage" aria-hidden="true" />
<span class="text">Vonage</span>
@@ -450,8 +426,6 @@ messaging.create_email(
<a
class="web-interactive-tag"
href="/docs"
target="_blank"
rel="noopener noreferrer"
>
<span
class="web-icon-appwrite u-small web-u-margin-inline-end-4"
@@ -568,14 +542,14 @@ messaging.create_email(
class="u-margin-block-start-16 u-min-width-0"
style="margin-block-end: 94px"
>
<MultiCodeContextless data={codeTopic} height={450} />
<MultiCodeContextless data={codeTopic} selected={Platform.ClientWeb} height={450} />
</div>
</div>
<div class="u-flex-vertical u-gap-8 u-min-width-0">
<h3 class="web-label web-u-color-text-primary">Send a message</h3>
<p class="web-description">Send a message to all targets on a topic.</p>
<div class="u-margin-block-start-16 u-min-width-0">
<MultiCodeContextless data={codeMessage} height={450} />
<MultiCodeContextless data={codeMessage} selected={Platform.ServerNodeJs} height={450} />
</div>
</div>
</div>
@@ -599,8 +573,6 @@ messaging.create_email(
class="web-card is-normal"
href="/docs/products/auth"
style="background: rgba(255, 255, 255, 0.04);"
target="_blank"
rel="noopener noreferrer"
>
<div
class="u-flex-vertical u-gap-8 web-u-padding-inline-8 web-u-padding-block-end-8"
@@ -628,8 +600,6 @@ messaging.create_email(
<a
class="web-card is-normal"
href="/docs/products/functions"
target="_blank"
rel="noopener noreferrer"
style="background: rgba(255, 255, 255, 0.04);"
>
<div
@@ -661,8 +631,6 @@ messaging.create_email(
<a
class="web-card is-normal"
href="/docs/products/databases"
target="_blank"
rel="noopener noreferrer"
style="background: rgba(255, 255, 255, 0.04);"
>
<div
@@ -693,8 +661,6 @@ messaging.create_email(
<a
class="web-card is-normal"
href="/docs/products/storage"
target="_blank"
rel="noopener noreferrer"
style="background: rgba(255, 255, 255, 0.04);"
>
<div
@@ -725,8 +691,6 @@ messaging.create_email(
<a
class="web-card is-normal"
href="/docs/apis/realtime"
target="_blank"
rel="noopener noreferrer"
style="background: rgba(255, 255, 255, 0.04);"
>
<div
@@ -897,6 +861,10 @@ messaging.create_email(
pointer-events: none;
}
.web-tag {
--p-tag-bg-color: var(--web-color-greyscale-100);
}
@media (min-width: 1024px) {
.hero {
padding-block-start: 0;

View File

@@ -1,10 +1,11 @@
---
layout: policy
title: Terms and Conditions
description: Review our Terms of Service to understand the rules and guidelines for using our open-source backend-as-a-service platform.
---
These Terms and Conditions ("Terms," "Terms and Conditions") govern your relationship with [https://appwrite.io](https://appwrite.io) website (the "Service") operated by Appwrite ("us," "we," or "our").
These Terms and Conditions ("Terms," "Terms and Conditions") govern your relationship with [Appwrite (https://appwrite.io)](https://appwrite.io) website (the "Service") operated by Appwrite ("us," "we," or "our").
Please read these Terms and Conditions carefully before using the Service.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

After

Width:  |  Height:  |  Size: 622 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 MiB

After

Width:  |  Height:  |  Size: 947 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

After

Width:  |  Height:  |  Size: 778 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 MiB

After

Width:  |  Height:  |  Size: 931 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 MiB

After

Width:  |  Height:  |  Size: 935 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 777 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 775 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

After

Width:  |  Height:  |  Size: 793 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 MiB

After

Width:  |  Height:  |  Size: 834 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 MiB

After

Width:  |  Height:  |  Size: 862 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 MiB

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1003 KiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 748 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 753 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 788 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

After

Width:  |  Height:  |  Size: 813 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 MiB

After

Width:  |  Height:  |  Size: 866 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 782 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 849 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 843 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 582 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 769 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 557 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1015 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1020 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

Some files were not shown because too many files have changed in this diff Show More