Compare commits
134 Commits
@nhost/rea
...
@nhost/rea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c3bede4051 | ||
|
|
e2e87bd0b2 | ||
|
|
c6bc105a6c | ||
|
|
097e304f9f | ||
|
|
fb34967ea6 | ||
|
|
20ab24d227 | ||
|
|
efd31f4bce | ||
|
|
30da899832 | ||
|
|
d14b0d4644 | ||
|
|
51d742b12c | ||
|
|
4f9b34a6a0 | ||
|
|
640d4521e2 | ||
|
|
8003dfed8b | ||
|
|
972af7bab1 | ||
|
|
2c35b02c83 | ||
|
|
c8c2f50fca | ||
|
|
3ef786392b | ||
|
|
b4b3c5edc2 | ||
|
|
02fb3eaa91 | ||
|
|
a5c21ed9f8 | ||
|
|
a36843296a | ||
|
|
318b0c8d54 | ||
|
|
2a684d3f84 | ||
|
|
0e870ad971 | ||
|
|
96a2c5f63f | ||
|
|
5dbad5feb2 | ||
|
|
6bb43b2536 | ||
|
|
7a13cb247f | ||
|
|
1521572f5f | ||
|
|
b8c150e6c3 | ||
|
|
f9ad440114 | ||
|
|
da6fab0767 | ||
|
|
4b4181a073 | ||
|
|
1fc001a31a | ||
|
|
e150a6d212 | ||
|
|
083dc4865b | ||
|
|
86c58f62d9 | ||
|
|
a2d31c119b | ||
|
|
50a4c2d9b8 | ||
|
|
29229734f0 | ||
|
|
5e1756681c | ||
|
|
476c732935 | ||
|
|
260c2eb51a | ||
|
|
b2fae7c78f | ||
|
|
ad52223fde | ||
|
|
c317669152 | ||
|
|
7d53883697 | ||
|
|
94105194ff | ||
|
|
433ceb508e | ||
|
|
dec2a83d0b | ||
|
|
e4751470b0 | ||
|
|
5300c09f56 | ||
|
|
5c13953a2b | ||
|
|
c42ffe6809 | ||
|
|
eb13606762 | ||
|
|
d0201c8a23 | ||
|
|
b1c652b550 | ||
|
|
5f980cb810 | ||
|
|
62c8c7a27f | ||
|
|
7c8f092667 | ||
|
|
eb36f6698d | ||
|
|
78ae8b52d0 | ||
|
|
828bf5bf2d | ||
|
|
d49d7d1ce0 | ||
|
|
d51389b50d | ||
|
|
8030f91f51 | ||
|
|
9a2afe7d77 | ||
|
|
3e9cf30c40 | ||
|
|
f18b58e2fc | ||
|
|
fa577f5c48 | ||
|
|
8969748d3c | ||
|
|
589d17968f | ||
|
|
44d092a997 | ||
|
|
d8983be968 | ||
|
|
1f8dd6dbd0 | ||
|
|
9b9d5def10 | ||
|
|
b4c08c999c | ||
|
|
79425ad8e6 | ||
|
|
a2a6790ae4 | ||
|
|
2ce1579ad6 | ||
|
|
a53d57a0e3 | ||
|
|
61df286fe8 | ||
|
|
0dce5d47f0 | ||
|
|
23dd5e9414 | ||
|
|
32346f4e5a | ||
|
|
69b3a6ba93 | ||
|
|
02aee323a2 | ||
|
|
9737fde711 | ||
|
|
63f607b8f1 | ||
|
|
c5ed2e0793 | ||
|
|
6f12144615 | ||
|
|
5f9b2f5b27 | ||
|
|
a525409bee | ||
|
|
5f718bf356 | ||
|
|
913aef1986 | ||
|
|
ce93615c1c | ||
|
|
d3028169df | ||
|
|
ce2a77a859 | ||
|
|
5bb64ae36b | ||
|
|
79258689ef | ||
|
|
8a1eefeee6 | ||
|
|
25f0d05fc2 | ||
|
|
ace5d89eed | ||
|
|
92cf6ae7bd | ||
|
|
648eac45b4 | ||
|
|
47936d4d1a | ||
|
|
1c82ab5346 | ||
|
|
479cbbe305 | ||
|
|
888a51ed33 | ||
|
|
92fbf2b425 | ||
|
|
e2940d7de3 | ||
|
|
c65c7f5538 | ||
|
|
11934f202d | ||
|
|
14f0d27c7d | ||
|
|
9933e4389e | ||
|
|
95ba1649d5 | ||
|
|
4c1992068e | ||
|
|
bbebf6ade2 | ||
|
|
83a00bbde1 | ||
|
|
60dc34a24b | ||
|
|
8cc5c94da5 | ||
|
|
83952b44b5 | ||
|
|
e609cc3fcb | ||
|
|
4dc31bd156 | ||
|
|
d57c0d6261 | ||
|
|
59a34143df | ||
|
|
214ae2fe19 | ||
|
|
bc86be70ef | ||
|
|
8555d30dab | ||
|
|
6f1ca70b7a | ||
|
|
aae6524acb | ||
|
|
9b834d8893 | ||
|
|
bd8ddaacc3 | ||
|
|
1cf7116bd8 |
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"packages/(docgen|hasura-auth-js|hasura-storage-js|nextjs|nhost-js|react|core)/src/**/*.{js,ts,jsx,tsx}": [
|
||||
"packages/(docgen|hasura-auth-js|hasura-storage-js|nextjs|nhost-js|react|core|vue)/src/**/*.{js,ts,jsx,tsx}": [
|
||||
"pnpm docgen",
|
||||
"git add docs"
|
||||
]
|
||||
|
||||
31
README.md
31
README.md
@@ -4,11 +4,11 @@
|
||||
|
||||
# Nhost
|
||||
|
||||
<a href="https://docs.nhost.io/get-started">Quickstart</a>
|
||||
<a href="https://docs.nhost.io/#quickstart">Quickstart</a>
|
||||
<span> • </span>
|
||||
<a href="http://nhost.io/">Website</a>
|
||||
<span> • </span>
|
||||
<a href="https://docs.nhost.io/get-started">Docs</a>
|
||||
<a href="https://docs.nhost.io">Docs</a>
|
||||
<span> • </span>
|
||||
<a href="https://nhost.io/blog">Blog</a>
|
||||
<span> • </span>
|
||||
@@ -134,13 +134,6 @@ Here are some ways of contributing to making Nhost better:
|
||||
<sub><b>Pilou</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/szilarddoro">
|
||||
<img src="https://avatars.githubusercontent.com/u/310881?v=4" width="100;" alt="szilarddoro"/>
|
||||
<br />
|
||||
<sub><b>Szilárd Dóró</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/elitan">
|
||||
<img src="https://avatars.githubusercontent.com/u/331818?v=4" width="100;" alt="elitan"/>
|
||||
@@ -148,6 +141,13 @@ Here are some ways of contributing to making Nhost better:
|
||||
<sub><b>Johan Eliasson</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/szilarddoro">
|
||||
<img src="https://avatars.githubusercontent.com/u/310881?v=4" width="100;" alt="szilarddoro"/>
|
||||
<br />
|
||||
<sub><b>Szilárd Dóró</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/gdangelo">
|
||||
<img src="https://avatars.githubusercontent.com/u/4352286?v=4" width="100;" alt="gdangelo"/>
|
||||
@@ -327,21 +327,28 @@ Here are some ways of contributing to making Nhost better:
|
||||
<sub><b>Jacob Duval</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/leothorp">
|
||||
<img src="https://avatars.githubusercontent.com/u/12928449?v=4" width="100;" alt="leothorp"/>
|
||||
<br />
|
||||
<sub><b>Leo Thorp</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/MarcelloTheArcane">
|
||||
<img src="https://avatars.githubusercontent.com/u/21159570?v=4" width="100;" alt="MarcelloTheArcane"/>
|
||||
<br />
|
||||
<sub><b>Max Reynolds</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/ghoshnirmalya">
|
||||
<img src="https://avatars.githubusercontent.com/u/6391763?v=4" width="100;" alt="ghoshnirmalya"/>
|
||||
<br />
|
||||
<sub><b>Nirmalya Ghosh</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/quentin-decre">
|
||||
<img src="https://avatars.githubusercontent.com/u/1137511?v=4" width="100;" alt="quentin-decre"/>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 61 KiB |
64
config/.eslint.base.js
Normal file
64
config/.eslint.base.js
Normal file
@@ -0,0 +1,64 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
es6: true,
|
||||
node: true
|
||||
},
|
||||
ignorePatterns: [
|
||||
'dist',
|
||||
'umd',
|
||||
'build',
|
||||
'.next',
|
||||
'node_modules',
|
||||
'tsup.config.ts',
|
||||
'__tests__',
|
||||
'__mocks__',
|
||||
'*.test.ts',
|
||||
'*.test.tsx',
|
||||
'*.spec.ts',
|
||||
'*.spec.tsx',
|
||||
'tests/**/*.ts',
|
||||
'tests/**/*.d.ts'
|
||||
],
|
||||
plugins: ['@typescript-eslint', 'simple-import-sort'],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020,
|
||||
sourceType: 'module'
|
||||
},
|
||||
rules: {
|
||||
'react/prop-types': 'off',
|
||||
'no-use-before-define': 'off',
|
||||
'simple-import-sort/exports': 'error',
|
||||
'simple-import-sort/imports': [
|
||||
'error',
|
||||
{
|
||||
groups: [
|
||||
// Node.js builtins. You could also generate this regex if you use a `.js` config.
|
||||
// For example: `^(${require("module").builtinModules.join("|")})(/|$)`
|
||||
[
|
||||
'^(assert|buffer|child_process|cluster|console|constants|crypto|dgram|dns|domain|events|fs|http|https|module|net|os|path|punycode|querystring|readline|repl|stream|string_decoder|sys|timers|tls|tty|url|util|vm|zlib|freelist|v8|process|async_hooks|http2|perf_hooks)(/.*|$)'
|
||||
],
|
||||
// Packages
|
||||
['^\\w'],
|
||||
// Internal packages.
|
||||
['^(@|config/)(/*|$)'],
|
||||
// Side effect imports.
|
||||
['^\\u0000'],
|
||||
// Parent imports. Put `..` last.
|
||||
['^\\.\\.(?!/?$)', '^\\.\\./?$'],
|
||||
// Other relative imports. Put same-folder imports and `.` last.
|
||||
['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'],
|
||||
// Style imports.
|
||||
['^.+\\.s?css$']
|
||||
]
|
||||
}
|
||||
],
|
||||
'import/no-anonymous-default-export': [
|
||||
'error',
|
||||
{
|
||||
allowArrowFunction: true,
|
||||
allowAnonymousFunction: true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,65 +1,6 @@
|
||||
const base = require('./.eslint.base')
|
||||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
es6: true,
|
||||
node: true
|
||||
},
|
||||
ignorePatterns: [
|
||||
'dist',
|
||||
'umd',
|
||||
'build',
|
||||
'.next',
|
||||
'node_modules',
|
||||
'tsup.config.ts',
|
||||
'__tests__',
|
||||
'__mocks__',
|
||||
'*.test.ts',
|
||||
'*.test.tsx',
|
||||
'*.spec.ts',
|
||||
'*.spec.tsx',
|
||||
'tests/**/*.ts',
|
||||
'tests/**/*.d.ts'
|
||||
],
|
||||
...base,
|
||||
extends: ['react-app', 'plugin:react/recommended', 'plugin:react-hooks/recommended'],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020,
|
||||
sourceType: 'module'
|
||||
},
|
||||
plugins: ['react', '@typescript-eslint', 'react-hooks', 'simple-import-sort'],
|
||||
rules: {
|
||||
'react/prop-types': 'off',
|
||||
'no-use-before-define': 'off',
|
||||
'simple-import-sort/exports': 'error',
|
||||
'simple-import-sort/imports': [
|
||||
'error',
|
||||
{
|
||||
groups: [
|
||||
// Node.js builtins. You could also generate this regex if you use a `.js` config.
|
||||
// For example: `^(${require("module").builtinModules.join("|")})(/|$)`
|
||||
[
|
||||
'^(assert|buffer|child_process|cluster|console|constants|crypto|dgram|dns|domain|events|fs|http|https|module|net|os|path|punycode|querystring|readline|repl|stream|string_decoder|sys|timers|tls|tty|url|util|vm|zlib|freelist|v8|process|async_hooks|http2|perf_hooks)(/.*|$)'
|
||||
],
|
||||
// Packages
|
||||
['^\\w'],
|
||||
// Internal packages.
|
||||
['^(@|config/)(/*|$)'],
|
||||
// Side effect imports.
|
||||
['^\\u0000'],
|
||||
// Parent imports. Put `..` last.
|
||||
['^\\.\\.(?!/?$)', '^\\.\\./?$'],
|
||||
// Other relative imports. Put same-folder imports and `.` last.
|
||||
['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'],
|
||||
// Style imports.
|
||||
['^.+\\.s?css$']
|
||||
]
|
||||
}
|
||||
],
|
||||
'import/no-anonymous-default-export': [
|
||||
'error',
|
||||
{
|
||||
allowArrowFunction: true,
|
||||
allowAnonymousFunction: true
|
||||
}
|
||||
]
|
||||
}
|
||||
plugins: [...base.plugins, 'react', 'react-hooks']
|
||||
}
|
||||
|
||||
10
config/.eslintrc.vue.js
Normal file
10
config/.eslintrc.vue.js
Normal file
@@ -0,0 +1,10 @@
|
||||
const base = require('./.eslint.base')
|
||||
module.exports = {
|
||||
...base,
|
||||
extends: ['plugin:import/recommended', 'plugin:import/typescript'],
|
||||
parser: 'vue-eslint-parser',
|
||||
parserOptions: {
|
||||
...base.parserOptions,
|
||||
parser: '@typescript-eslint/parser'
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,8 @@
|
||||
"@nhost/nhost-js": ["../packages/nhost-js/src/index.ts"],
|
||||
"@nhost/react": ["../packages/react/src/index.ts"],
|
||||
"@nhost/react-apollo": ["../packages/react-apollo/src/index.ts"],
|
||||
"@nhost/react-auth": ["../packages/react-auth/src/index.ts"]
|
||||
"@nhost/react-auth": ["../packages/react-auth/src/index.ts"],
|
||||
"@nhost/vue": ["../packages/vue/src/index.ts"]
|
||||
}
|
||||
},
|
||||
"exclude": [
|
||||
|
||||
@@ -53,6 +53,7 @@ export default defineConfig({
|
||||
globals: {
|
||||
'graphql/language/printer': 'graphql/language/printer',
|
||||
'@apollo/client': '@apollo/client',
|
||||
'@apollo/client/core': '@apollo/client/core',
|
||||
'@apollo/client/link/context': '@apollo/client/link/context',
|
||||
'@apollo/client/link/subscriptions': '@apollo/client/link/subscriptions',
|
||||
'@apollo/client/utilities': '@apollo/client/utilities',
|
||||
|
||||
10
config/vite.vue.config.js
Normal file
10
config/vite.vue.config.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
import baseLibConfig from './vite.lib.config'
|
||||
|
||||
export default defineConfig({
|
||||
...baseLibConfig,
|
||||
plugins: [vue(), ...baseLibConfig.plugins]
|
||||
})
|
||||
13
config/vite.vue.dev.config.js
Normal file
13
config/vite.vue.dev.config.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
import viteVueConfig from './vite.vue.config'
|
||||
|
||||
export default defineConfig({
|
||||
...viteVueConfig,
|
||||
build: {
|
||||
...viteVueConfig.build,
|
||||
watch: {
|
||||
buildDelay: 500
|
||||
}
|
||||
}
|
||||
})
|
||||
45
config/vite.vue.umd.config.js
Normal file
45
config/vite.vue.umd.config.js
Normal file
@@ -0,0 +1,45 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import { defineConfig } from 'vite'
|
||||
import dts from 'vite-plugin-dts'
|
||||
import tsconfigPaths from 'vite-tsconfig-paths'
|
||||
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
import baseLibConfig from './vite.lib.config'
|
||||
|
||||
const PWD = process.env.PWD
|
||||
const pkg = require(path.join(PWD, 'package.json'))
|
||||
|
||||
const deps = [...Object.keys(Object.assign({}, pkg.peerDependencies))]
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
vue(),
|
||||
tsconfigPaths(),
|
||||
dts({
|
||||
exclude: ['**/*.spec.ts', '**/*.test.ts', '**/tests/**'],
|
||||
afterBuild: () => {
|
||||
const types = fs.readdirSync(path.join(PWD, 'umd/src'))
|
||||
types.forEach((file) => {
|
||||
fs.renameSync(path.join(PWD, 'umd/src', file), path.join(PWD, 'umd', file))
|
||||
})
|
||||
fs.rmdirSync(path.join(PWD, 'umd/src'))
|
||||
}
|
||||
})
|
||||
],
|
||||
build: {
|
||||
...(baseLibConfig.build || {}),
|
||||
outDir: 'umd',
|
||||
lib: {
|
||||
...(baseLibConfig.build?.lib || {}),
|
||||
fileName: pkg.name.replace(/@nhost\//g, ''),
|
||||
formats: ['umd']
|
||||
},
|
||||
rollupOptions: {
|
||||
...(baseLibConfig.build?.rollupOptions || {}),
|
||||
external: (id) => deps.some((dep) => id.startsWith(dep))
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -1,125 +0,0 @@
|
||||
---
|
||||
title: 'Authenticate users'
|
||||
slug: /get-started/authentication
|
||||
---
|
||||
|
||||
In the previous section, you defined `select` permissions for the `public` role. You will now add `insert` and `select` permissions for authenticated users to secure your app's GraphQL API with authentication.
|
||||
|
||||
> Nhost's authentication service lets you deliver frictionless registration and login experiences to your users. We support most social providers and different methods such as email & password and passwordless (magic link).
|
||||
|
||||
---
|
||||
|
||||
## Insert a test user
|
||||
|
||||
Manually create a user by going to your app's **Users** tab (top menu) and clicking on **Add User**.
|
||||
|
||||
<video width="99%" loop="" muted="" playsInline="" controls="true">
|
||||
<source src="/videos/add-user.mp4" type="video/mp4" />
|
||||
</video>
|
||||
|
||||
You will now use that newly created user. We'll use this newly created user to make authenticated requests to the GraphQL API.
|
||||
|
||||
---
|
||||
|
||||
## Sign in and query data
|
||||
|
||||
Add the following code to sign in the new user and request the list of todos again:
|
||||
|
||||
```js
|
||||
import { NhostClient } from '@nhost/nhost-js';
|
||||
|
||||
const nhost = new NhostClient({
|
||||
backendUrl: 'https://[app-subdomain].nhost.run',
|
||||
})(async () => {
|
||||
// Sign in user
|
||||
const signInResponse = await nhost.auth.signIn({
|
||||
email: 'joe@example.com',
|
||||
password: 'securepassword',
|
||||
});
|
||||
|
||||
// Handle sign-in error
|
||||
if (signInResponse.error) {
|
||||
throw signInResponse.error;
|
||||
}
|
||||
|
||||
// Get todos
|
||||
const todos = await nhost.graphql.request(`
|
||||
query {
|
||||
todos {
|
||||
id
|
||||
created_at
|
||||
name
|
||||
is_completed
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
console.log(JSON.stringify(todos.data, null, 2));
|
||||
})();
|
||||
```
|
||||
|
||||
Why is the return value `null`? Because when making GraphQL requests as an authenticated user, the `user` role is assumed.
|
||||
|
||||
> For authenticated requests, there is always the option to override the default `user` role with any other valid role.
|
||||
|
||||
To prepare our database and GraphQL API to work for signed-in users we need to do two things:
|
||||
|
||||
1. Add a `user_id` column to the `todos` table, so we know what todo belongs to which user.
|
||||
2. Use the `user` role instead of the `public` role for permissions.
|
||||
|
||||
## Add `user_id` column
|
||||
|
||||
Before adding the `user_id` column, let's delete all existing todos.
|
||||
|
||||
Then add the `user_id` column as a `UUID` type. Make sure that `nullable` is **not** checked. This will ensure that all todos must have a `user_id` value.
|
||||
|
||||
At last, we'll create a connection between the `todos` table and the `users` table. For that, we need to do yet another two things:
|
||||
|
||||
1. Create a Foreign Key (FK) between `todos` and `auth.users.id`.
|
||||
2. Let Hasura track the relationship between the two tables.
|
||||
|
||||
<video width="99%" loop="" muted="" playsInline="" controls="true">
|
||||
<source src="/videos/user-id-column.mp4" type="video/mp4" />
|
||||
</video>
|
||||
|
||||
### Create FK
|
||||
|
||||
Create a FK between the `auth.users.id` column and the `public.todos.user_id` column. See video above.
|
||||
|
||||
### Track relationship
|
||||
|
||||
Click on the `public` schema and track the untracked foreign key relationship. Then click on the `auth` schema and track the relationship again. See video above.
|
||||
|
||||
We track these relationships to create the GrpahQL relationships between the `todos` table to the `users` table and the `users` table to the `todos` table.
|
||||
|
||||
Ok, our `user_id` column is added and connected correctly. Let's continue with setting permissions for signed-in users.
|
||||
|
||||
## Permissions for signed-in users
|
||||
|
||||
Let us organize the permissions so it works for signed in users too.
|
||||
|
||||
### Remove permissions for the public role
|
||||
|
||||
We won't use the `public` role anymore, so let's remove all permission for that role.
|
||||
|
||||

|
||||
|
||||
Now we'll add permissions for the `user` role.
|
||||
|
||||
> Signed-in users use the `user` role by default
|
||||
|
||||
### Insert permission
|
||||
|
||||
First, we'll set the **Insert permission**.
|
||||
|
||||
A user can only insert `name` because all other columns will be set automatically. More specifically, `user_id` is set to the user's id making the request (`x-hasura-user-id`) and is configured in the `Column presets` section. See the image below.
|
||||
|
||||

|
||||
|
||||
### Select permission
|
||||
|
||||
For **Select permission**, set a **custom check** so users can only select todos where `user_id` is the same as their user id. In other words: users are only allowed to select their own todos. See the image below.
|
||||
|
||||

|
||||
|
||||
Now rerun the app. New todos are inserted, and only todos for the user are fetched and displayed. Your backend is successfully secured!
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"label": "CLI",
|
||||
"position": 8
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
---
|
||||
title: 'CLI from Zero to Production'
|
||||
---
|
||||
|
||||
In the previous tutorials, we tested various parts of Nhost, such as:
|
||||
|
||||
- Database
|
||||
- GraphQL API
|
||||
- Permission
|
||||
- JavaScript SDK
|
||||
- Authentication
|
||||
|
||||
All changes we did to our database and API happened directly in production of our Nhost app.
|
||||
|
||||
It's not ideal for making changes in production because you might break things, which will affect all users of your app.
|
||||
|
||||
Instead, it's recommended to make changes and test your app locally before deploying those changes to production.
|
||||
|
||||
To do changes locally, we need to have a complete Nhost app running locally, which the Nhost CLI does.
|
||||
|
||||
The Nhost CLI matches your production application in a local environment, this way you can make changes and test your code before deploying your changes to production.
|
||||
|
||||
## Recommended workflow with Nhost
|
||||
|
||||
1. Develop locally using the Nhost CLI.
|
||||
2. Push changes to GitHub.
|
||||
3. Nhost automatically applies changes to production.
|
||||
|
||||
## What you'll learn in this guide:
|
||||
|
||||
- Use the Nhost CLI to create a local environment
|
||||
- Connect a GitHub repository with a Nhost app
|
||||
- Deploy local changes to production
|
||||
@@ -1,37 +0,0 @@
|
||||
---
|
||||
title: 'Install the CLI'
|
||||
---
|
||||
|
||||
Install the Nhost CLI using the following command:
|
||||
|
||||
```bash
|
||||
sudo curl -L https://raw.githubusercontent.com/nhost/cli/main/get.sh | bash
|
||||
```
|
||||
|
||||
Initialize a new Nhost App locally:
|
||||
|
||||
```bash
|
||||
nhost init -n "nhost-example-app" && cd nhost-example-app
|
||||
```
|
||||
|
||||
And initialize the GitHub repository in the same folder:
|
||||
|
||||
```bash
|
||||
echo "# nhost-example-app" >> README.md
|
||||
git init
|
||||
git add README.md
|
||||
git commit -m "first commit"
|
||||
git branch -M main
|
||||
git remote add origin https://github.com/[github-username]/nhost-example-app.git
|
||||
git push -u origin main
|
||||
```
|
||||
|
||||
Now go back to the **Nhost Console** and click **Deployments**. You just made a new deployment to your Nhost app!
|
||||
|
||||

|
||||
|
||||
If you click on the deployment you can see that nothing was really deployed. That’s because we just made a change to the README file.
|
||||
|
||||

|
||||
|
||||
Let's do some local backend changes!
|
||||
@@ -1,81 +0,0 @@
|
||||
---
|
||||
title: 'Local changes'
|
||||
---
|
||||
|
||||
Start Nhost locally:
|
||||
|
||||
```bash
|
||||
nhost dev
|
||||
```
|
||||
|
||||
:::tip
|
||||
Make sure you have [Docker](https://www.docker.com/get-started) installed on your computer. It’s required for Nhost to work.
|
||||
:::
|
||||
|
||||
The `nhost dev` command will automatically start a complete Nhost environment locally on your computer using:
|
||||
|
||||
- Postgres
|
||||
- Hasura
|
||||
- Authentication
|
||||
- Storage
|
||||
- Serverless Functions
|
||||
- Mailhog
|
||||
|
||||
You use this local environment to do changes and testing before you deploy your changes to production.
|
||||
|
||||
Running `nhost dev` also starts the Hasura Console.
|
||||
|
||||
:::tip
|
||||
It's important that you use the Hasura Console that is started automatically when you do changes. This way, changes are automatically tracked for you.
|
||||
:::
|
||||
|
||||

|
||||
|
||||
In the Hasura Console, create a new table `customers` with two columns:
|
||||
|
||||
- id
|
||||
- name
|
||||
|
||||
<video
|
||||
src="/videos/cli-workflow/hasura-create-customers-table.mp4"
|
||||
width="100%"
|
||||
controls
|
||||
/>
|
||||
|
||||
When we created the `customers` table there was also a migration created automatically. The migration was created at under `nhost/migrations/default`.
|
||||
|
||||
```bash
|
||||
$ ls -la nhost/migrations/default
|
||||
total 0
|
||||
drwxr-xr-x 3 eli staff 96 Feb 7 16:19 .
|
||||
drwxr-xr-x 3 eli staff 96 Feb 7 16:19 ..
|
||||
drwxr-xr-x 4 eli staff 128 Feb 7 16:19 1644247179684_create_table_public_customers
|
||||
```
|
||||
|
||||
This database migration has only been applied locally, meaning, you created the `customers` table locally but it does not (yet) exists in production.
|
||||
|
||||
To apply the local change to production we need to commit the changes and push it to GitHub. Nhost will then automatically pick up the change in the repository and apply the changes.
|
||||
|
||||
:::tip
|
||||
You can commit and push files in another terminal while still having `nhost dev` running.
|
||||
:::
|
||||
|
||||
```bash
|
||||
git add -A
|
||||
git commit -m "Initialized Nhost and added a customers table"
|
||||
git push
|
||||
```
|
||||
|
||||
Head over to the **Deployments** tab in the **Nhost console** to see the deployment.
|
||||
|
||||

|
||||
|
||||
Once the deployment finishes the `customers` table is created in production.
|
||||
|
||||

|
||||
|
||||
We've now completed the recommended workflow with Nhost:
|
||||
|
||||
1. Develop locally using the Nhost CLI.
|
||||
2. Push changes to GitHub.
|
||||
3. Nhost deploys changes to production.
|
||||
@@ -1,170 +0,0 @@
|
||||
---
|
||||
title: 'Metadata and Serverless Functions'
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
In the previous section, we only created a new table; `customers`. Using the CLI you can also do changes to other parts of your backend.
|
||||
|
||||
There are three things the CLI and the GitHub integration track and applies to production:
|
||||
|
||||
1. Database migrations
|
||||
2. Hasura Metadata
|
||||
3. Serverless Functions
|
||||
|
||||
For this section, let's do one change to the Hasura metadata and create one serverless function
|
||||
|
||||
### Hasura Metadata
|
||||
|
||||
We'll add permissions to the `users` table, making sure users can only see their own data. For this, go to the `auth` schema and click on the `users` table. then click on **Permissions** and enter a new role **user** and create a new **select** permission for that role**.**
|
||||
|
||||
Create the permission **with custom check**:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": {
|
||||
"_eq": "X-Hasura-User-Id"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Select the following columns:
|
||||
|
||||
- id
|
||||
- created_at
|
||||
- display_name
|
||||
- avatar_url
|
||||
- email
|
||||
|
||||
Then click **Save permissions**.
|
||||
|
||||
<video
|
||||
src="/videos/cli-workflow/hasura-user-permissions.mp4"
|
||||
width="100%"
|
||||
controls
|
||||
/>
|
||||
|
||||
Now, let's do a `git status` again to confirm the permission changes we did was tracked locally in your git repository.
|
||||
|
||||

|
||||
|
||||
We can now commit this change:
|
||||
|
||||
```bash
|
||||
git add -A
|
||||
git commit -m "added permission for uses"
|
||||
```
|
||||
|
||||
Now let's create a serverless function before we push all changes to GitHub so Nhost can deploy our changes.
|
||||
|
||||
### Serverless Function
|
||||
|
||||
A serverless function is a pieces of code written in JavaScript or TypeScript that take an HTTP request and returns a response.
|
||||
|
||||
Here's an example:
|
||||
|
||||
```bash
|
||||
import { Request, Response } from 'express'
|
||||
|
||||
export default (req: Request, res: Response) => {
|
||||
res.status(200).send(`Hello ${req.query.name}!`)
|
||||
}
|
||||
```
|
||||
|
||||
Serverless functions are placed in the `functions/` folder of your repository. Every file will become its own endpoint.
|
||||
|
||||
Before we create our serverless function we'll install `express`, which is a requirement for serverless functions to work.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="npm" label="npm" default>
|
||||
|
||||
```bash
|
||||
npm install express
|
||||
npm install -d @types/node @types/express
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="yarn" label="Yarn">
|
||||
|
||||
```bash
|
||||
yarn add express
|
||||
yarn add -D @types/node @types/express
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Then we'll create a file `functions/time.ts`
|
||||
|
||||
In the file `time.ts` we'll add the following code to create our serverless function:
|
||||
|
||||
```bash
|
||||
import { Request, Response } from 'express';
|
||||
|
||||
export default (req: Request, res: Response) => {
|
||||
return res
|
||||
.status(200)
|
||||
.send(`Hello ${req.query.name}! It's now: ${new Date().toUTCString()}`);
|
||||
};
|
||||
```
|
||||
|
||||
We can now test the function locally. Locally, the backend URL is `http://localhost:1337`. Functions are under `/v1/functions`. And every function's path and filename becomes an API endpoint.
|
||||
|
||||
This means our function `functions/time.ts` is at `http://localhost:1337/v1/functions/time`.
|
||||
|
||||
Let's use curl to test our new function:
|
||||
|
||||
```bash
|
||||
curl http://localhost:1337/v1/functions/time
|
||||
Hello undefined! It's now: Sun, 06 Feb 2022 17:44:45 GMT
|
||||
```
|
||||
|
||||
And with a query parameter with our name:
|
||||
|
||||
```bash
|
||||
curl http://localhost:1337/v1/functions/time\?name\=Johan
|
||||
Hello Johan! It's now: Sun, 06 Feb 2022 17:44:48 GMT
|
||||
```
|
||||
|
||||
Again, let's use `git status` to see the changes we did to create our serverless function.
|
||||
|
||||
Now let's commit the changes and push them to GitHub.
|
||||
|
||||
```bash
|
||||
git add -A
|
||||
git commit -m "added serverless function"
|
||||
git push
|
||||
```
|
||||
|
||||
In the Nhost Console, click on the new deployment to see details.
|
||||
|
||||

|
||||
|
||||
After Nhost has finished deploying your changes we can test them in production. First let's confirm that the user permissions are applied.
|
||||
|
||||

|
||||
|
||||
Then, let's confirm that the serverless function was deployed. Again, we'll use curl:
|
||||
|
||||
```bash
|
||||
curl https://your-backend-url.nhost.run/v1/functions/time\?name\=Johan
|
||||
```
|
||||
|
||||

|
||||
|
||||
## Conclusion
|
||||
|
||||
In this tutorial we have installed the Nhost CLI and created a local Nhost environment to do local development and testing.
|
||||
|
||||
In the local environment we've made changes to our database, to Hasura's metadata and created a serverless function.
|
||||
|
||||
We've connected a GitHub repository and pushed our changes to GitHub.
|
||||
|
||||
We've seen Nhost automatically deploying our changes and we've verified that the changes were applied.
|
||||
|
||||
In summary, we've set up a productive environment using the recommended Nhost workflow:
|
||||
|
||||
1. Develop locally using the Nhost CLI.
|
||||
2. Push changes to GitHub.
|
||||
3. Nhost deploys changes to production.
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
title: 'Workflow setup'
|
||||
---
|
||||
|
||||
What follows is a detailed tutorial on how you setup Nhost for this workflow
|
||||
|
||||
### Create Nhost App
|
||||
|
||||
Create a **new Nhost app** for this tutorial.
|
||||
|
||||
:::tip
|
||||
It's important that you create a **new** Nhost app for this guide instead of reusing an old Nhost app because we want to start with a clean Nhost app.
|
||||
:::
|
||||
|
||||

|
||||
|
||||
### Create new GitHub Repository
|
||||
|
||||
Create a new GitHub repository for your new Nhost app. The repo can be either private or public.
|
||||
|
||||

|
||||
|
||||
## Connect GitHub Repository to Nhost App
|
||||
|
||||
In the Nhost Console, go to the dashboard of your Nhost app and click **Connect to GitHub**.
|
||||
|
||||
<video
|
||||
src="/videos/cli-workflow/connect-github-repo.mp4"
|
||||
width="100%"
|
||||
controls
|
||||
/>
|
||||
@@ -1,36 +0,0 @@
|
||||
---
|
||||
title: 'Welcome to Nhost'
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
Nhost is an open-source, real-time, server-less backend platform for building reliable apps that scale with your business.
|
||||
|
||||
---
|
||||
|
||||
## Components
|
||||
|
||||
Nhost uses an opinionated set of open-source components.
|
||||
|
||||
#### Database
|
||||
|
||||
Your application gets its own PostgreSQL database, the world's most advanced relational database.
|
||||
|
||||
#### GraphQL API
|
||||
|
||||
Highly performant and real-time GraphQL API with Hasura.
|
||||
|
||||
#### Authentication and storage
|
||||
|
||||
User management & file storage seamlessly integrated with Hasura permissions.
|
||||
|
||||
#### Serverless functions
|
||||
|
||||
JavaScript and TypeScript functions run your custom code in the backend.
|
||||
|
||||
---
|
||||
|
||||
## Get started
|
||||
|
||||
Follow our [Quick start](/get-started/quick-start) guide to build your first app.
|
||||
|
||||
Check out [Nhost on GitHub](https://github.com/nhost/nhost). Give us a star, and feel free to open a discussion for any feature requests as well.
|
||||
@@ -1,36 +0,0 @@
|
||||
---
|
||||
title: 'Create your app'
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
Let's create a simple todo-app using Nhost. In a todo-app, a user should be able to create list items for their account (CRUD) and not have anyone else see them (permissions).
|
||||
|
||||
To implement this todo-app with Nhost, we'll briefly cover these topics:
|
||||
|
||||
- Creating a new app on Nhost
|
||||
- Defining a database schema
|
||||
- Inserting data
|
||||
- Setting permissions
|
||||
- Querying data via the GraphQL API
|
||||
|
||||
By the end of this quick-start, you will better understand what Nhost is and what it does for you.
|
||||
|
||||
---
|
||||
|
||||
## Log in to Nhost
|
||||
|
||||
Go to [app.nhost.io](https://app.nhost.io) and sign up for a new account if you don't have one already.
|
||||
|
||||
---
|
||||
|
||||
## Create app
|
||||
|
||||
Press the **"New App"** button on the console's home page. Choose a name and pick the region closest to your users.
|
||||
|
||||
You'll be all set with the Default Workspace and the Free plan for now.
|
||||
|
||||

|
||||
|
||||
Creating a new app takes around 20 seconds or so. During this time, Nhost sets up your app's entire backend and infrastructure.
|
||||
|
||||
Once the setup completes, you'll automatically see the app dashboard, and you're ready to define your app's database schema.
|
||||
@@ -1,110 +0,0 @@
|
||||
---
|
||||
title: 'JavaScript client'
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
In the previous section, you used the Hasura Console to fetch a list of todos. Now, you will write a small JavaScript client to interact and retrieve todos from your Nhost app.
|
||||
|
||||
### Frontend frameworks
|
||||
|
||||
Nhost is framework-agnostic and works with any frontend you might build. You can also connect to Nhost from your server-side if you wish.
|
||||
|
||||
In this guide, we'll keep the example simple. We're not using a frontend framework. In a real-life scenario, you'd probably build a frontend client with a framework such as React, Vue, Svelte or React Native.
|
||||
|
||||
---
|
||||
|
||||
## Setup
|
||||
|
||||
:::info
|
||||
|
||||
Make sure you have [Node.js](https://nodejs.org) and [npm](https://docs.npmjs.com/getting-started) or [Yarn](https://classic.yarnpkg.com/lang/en/docs/install) installed.
|
||||
|
||||
:::
|
||||
|
||||
Create a new folder called `nhost-todos`, initialize a new JavaScript app there, and install the Nhost JavaScript SDK:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="npm" label="npm" default>
|
||||
|
||||
```bash
|
||||
npm init -y
|
||||
npm install @nhost/nhost-js graphql
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="yarn" label="Yarn">
|
||||
|
||||
```bash
|
||||
yarn init -y
|
||||
yarn add @nhost/nhost-js graphql
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::caution attention
|
||||
You might have to edit the `package.json` file and add/change the `type` object to `module` (`"type": "module"`).
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## Initialize Nhost
|
||||
|
||||
In the new directory, create a file called `index.js`.
|
||||
|
||||
Enter the following code into this file. It will initialize a new `NhostClient` that will interact with your backend:
|
||||
|
||||
```js
|
||||
import { NhostClient } from '@nhost/nhost-js';
|
||||
|
||||
const nhost = new NhostClient({
|
||||
backendUrl: 'https://[app-subdomain].nhost.run', // replace this with the backend URL of your app
|
||||
});
|
||||
|
||||
console.log(nhost.graphql.getUrl());
|
||||
```
|
||||
|
||||
Run the code in your terminal. You should see your app's GraphQL endpoint URL:
|
||||
|
||||
```bash
|
||||
➜ node index.js
|
||||
|
||||
https://[app-subdomain].nhost.run/v1/graphql
|
||||
```
|
||||
|
||||
### Query todos
|
||||
|
||||
If you now add the following GraphQL query to the client, let's see what happens when you run the updated version:
|
||||
|
||||
```js
|
||||
import { NhostClient } from '@nhost/nhost-js';
|
||||
|
||||
const nhost = new NhostClient({
|
||||
backendUrl: 'https://[app-subdomain].nhost.run',
|
||||
})(async () => {
|
||||
// nhost.graphql.request returns a promise, so we use await here
|
||||
const todos = await nhost.graphql.request(`
|
||||
query {
|
||||
todos {
|
||||
id
|
||||
created_at
|
||||
name
|
||||
is_completed
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
// Print todos to console
|
||||
console.log(JSON.stringify(todos.data, null, 2));
|
||||
})();
|
||||
```
|
||||
|
||||
```bash
|
||||
➜ node index.js
|
||||
|
||||
null
|
||||
```
|
||||
|
||||
`null` is printed. Why is that? Let's find out.
|
||||
@@ -1,53 +0,0 @@
|
||||
---
|
||||
title: 'Set permissions'
|
||||
---
|
||||
|
||||
While using the Hasura Console, you could fetch the todos because the **admin** role is enabled by default but when building your applications with a client, you want to define permissions using **roles** that your users can assume when making requests.
|
||||
|
||||
Hasura supports role-based access control. You create rules for each role, table, and operation (select, insert, update and delete) that can check dynamic session variables, like user ID.
|
||||
|
||||
## Unauthenticated users
|
||||
|
||||
Use the `public` role in permissions when you want some data to be accessed by anyone without being signed in. The `public` role is the default role in all unauthenticated requests.
|
||||
|
||||
Generally speaking, the `public` role should not have insert, update or delete permissions defined.
|
||||
|
||||
### Setting `public` permissions
|
||||
|
||||
In Hasura Console, go to the **Data** tab, click on the **todos** table, then click **Permissions**. Add a new role called `public` and click on **select**. The permission options for the select operation show up below.
|
||||
|
||||
Add the following permissions:
|
||||
|
||||

|
||||
|
||||
Rerun the program. Now you see all todos.
|
||||
|
||||
```bash
|
||||
➜ node index.js
|
||||
|
||||
{
|
||||
"todos": [
|
||||
{
|
||||
"id": "558b9754-bb18-4abd-83d9-e9056934e812",
|
||||
"created_at": "2021-12-01T17:05:09.311362+00:00",
|
||||
"name": "write docs",
|
||||
"is_completed": false
|
||||
},
|
||||
{
|
||||
"id": "480369c8-6f57-4061-bfdf-9ead647e10d3",
|
||||
"created_at": "2021-12-01T17:05:20.5693+00:00",
|
||||
"name": "cook dinner",
|
||||
"is_completed": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
There are two reasons why the request succeeded:
|
||||
|
||||
1. Nhost sets the `public` role for every unauthenticated GraphQL request.
|
||||
2. You explicitly defined permissions for the `public` role.
|
||||
|
||||
It is essential to understand that Hasura has an **allow nothing by default** policy to ensure that only roles and permissions you define explicitly have access to the GraphQL API.
|
||||
@@ -1,95 +0,0 @@
|
||||
---
|
||||
title: 'Define schema'
|
||||
---
|
||||
|
||||
To implement an app for managing a todo list, let's ensure we have database tables for storing todos and users.
|
||||
|
||||
---
|
||||
|
||||
## Open Hasura Console
|
||||
|
||||
Hasura generates real-time GraphQL APIs, but it also provides a web console for manipulating the schema and data of your database.
|
||||
|
||||
Go to the **Data** tab on your app's dashboard and select **Open Hasura**. Remember to copy the admin secret.
|
||||
|
||||
The Hasura Console of your app's dedicated Hasura instance will open in a new tab. You can use Hasura Console to manage your app's schema, data, permissions, and event triggers.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## Users table
|
||||
|
||||
You should see all your database tables on the left-hand side of the screen. You should see multiple different **schemas** displayed as folders:
|
||||
|
||||
- `public` schema for your app's custom tables
|
||||
- `auth` and `storage` schemas for Nhost's user management and file storage
|
||||
|
||||
If you open the `auth` schema, you'll see that your app already has a `users` table, so you don't have to create one.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## Create todos table
|
||||
|
||||
In Hasura Console, go to the **data** tab, then click **Create Table**. Name this table `todos`.
|
||||
|
||||
### Add frequently used columns
|
||||
|
||||
`id` and `created_at` columns are standard and can be added with two clicks. Click **Frequently used columns** and create them:
|
||||
|
||||
- `id` (UUID)
|
||||
- `created_at` (timestamp)
|
||||
|
||||
Using frequently used columns ensures the columns get the right name, type, and default value.
|
||||
|
||||

|
||||
|
||||
### Add custom columns
|
||||
|
||||
Add two more columns manually:
|
||||
|
||||
- `name` (text)
|
||||
- `is_completed` (boolean)
|
||||
|
||||
Make sure to set the default value of `is_completed` to `false`.
|
||||
|
||||

|
||||
|
||||
This is all we need! A new table will be created when you click **Add Table**.
|
||||
|
||||
---
|
||||
|
||||
## Insert data
|
||||
|
||||
Go to the **Insert Row** tab to add some data to your database.
|
||||
|
||||
<video width="99%" loop="" muted="" playsInline="" controls="true">
|
||||
<source src="/videos/insert-todos.mp4" type="video/mp4" />
|
||||
</video>
|
||||
|
||||
---
|
||||
|
||||
## Query data
|
||||
|
||||
Now that we have data in our database, we can retrieve it via a GraphQL API. Go to the **API** tab in the main menu. You can use this view to make GraphQL requests that query or mutate data in your database.
|
||||
|
||||
Paste the following GraphQL query into the form and press the "play" button:
|
||||
|
||||
```graphql
|
||||
query {
|
||||
todos {
|
||||
id
|
||||
created_at
|
||||
name
|
||||
is_completed
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You should see the todos you just inserted show up as output on the right-hand side.
|
||||
|
||||
### Admin role
|
||||
|
||||
All requests in the Hasura Console use the `admin` role by default. This role has access to all tables and permissions.
|
||||
@@ -1,104 +0,0 @@
|
||||
---
|
||||
title: 'Upgrade from v1 to v2'
|
||||
---
|
||||
|
||||
Upgrading from Nhost v1 to v2 requires database schema and Hasura metadata changes.
|
||||
|
||||
---
|
||||
|
||||
## Upgrade Steps
|
||||
|
||||
### Create a new Nhost v2 app locally
|
||||
|
||||
:::tip
|
||||
Make sure you have the [Nhost CLI](/reference/cli) installed
|
||||
:::
|
||||
|
||||
```bash
|
||||
nhost init my-nhost-v2-app
|
||||
cd my-nhost-v2-app
|
||||
```
|
||||
|
||||
### Update config
|
||||
|
||||
Update `version: 3` to `version: 2` in `nhost/config.yaml`. This will update Hasura's configuration version, and we need to downgrade the version when we export migrations and metadata.
|
||||
|
||||
### Export current migrations and metadata from Nhost v1
|
||||
|
||||
Inside the `nhost/` folder of your app, run:
|
||||
|
||||
```bash
|
||||
hasura migrate create init --from-server --endpoint=[v1-endpoint] --admin-secret=[v1-admin-secret]
|
||||
|
||||
hasura metadata export --endpoint=[v1-endpoint] --admin-secret=[v1-admin-secret]
|
||||
```
|
||||
|
||||
### Update Migrations
|
||||
|
||||
Make the following changes manually to your migrations.
|
||||
|
||||
:::tip
|
||||
The migration file is located at `nhost/migrations/[timestamp]/up.sql`.
|
||||
:::
|
||||
|
||||
- Add `OR REPLACE` after `CREATE` for the `public.set_current_timestamp_updated_at` function
|
||||
- Delete all `auth.*` tables and functions (if any).
|
||||
- Delete `public.users` table and everything related to the table such as constraints, triggers, etc.
|
||||
- Update FK references from `public.users` to `auth.users` (if any).
|
||||
|
||||
### Update Metadata
|
||||
|
||||
Make the following changes manually to your metadata.
|
||||
|
||||
:::tip
|
||||
The metadata is located at `nhost/metadata/tables.yaml`.
|
||||
:::
|
||||
|
||||
- Delete tracking all tables in the `auth` schema.
|
||||
- Delete tracking the `public.users` table.
|
||||
- Update all references to `users` from the `public` to `auth` schema.
|
||||
|
||||
### Start nhost
|
||||
|
||||
Start Nhost locally using the [CLI](/reference/cli). From the root of your app, run:
|
||||
|
||||
```bash
|
||||
nhost -d
|
||||
```
|
||||
|
||||
:::tip
|
||||
Running Nhost applies your local database migrations and Hasura metadata.
|
||||
:::
|
||||
|
||||
### Restart Auth and Storage containers
|
||||
|
||||
Open Docker UI and restart Hasura Auth and Hasura Storage. Restarting those containers applies new metadata, effectively tracking everything in the `auth` and the `storage` schema.
|
||||
|
||||
### Delete migrations and metadata
|
||||
|
||||
Delete the local migrations and metadata.
|
||||
|
||||
```bash
|
||||
rm -rf nhost/migrations nhost/metadata
|
||||
```
|
||||
|
||||
### Update config (again)
|
||||
|
||||
Update `config: 2` to `config: 3` in `nhost/config.yaml`.
|
||||
|
||||
### Pull migrations and metadata from our local instance
|
||||
|
||||
In the `nhost/` folder, run the following command:
|
||||
|
||||
```bash
|
||||
hasura migrate create init --from-server --endpoint=http://localhost:[hasura-port] --admin-secret=nhost-admin-secret
|
||||
hasura metadata export --endpoint=http://localhost:[hasura-port] --admin-secret=nhost-admin-secret
|
||||
```
|
||||
|
||||
:::warning
|
||||
You cannot use port `1337` in the commands above. You have to use the specific port Hasura uses. Go to the Hasura Console under API and look for the port Hasura is using under GraphQL Endpoint.
|
||||
:::
|
||||
|
||||
### Done
|
||||
|
||||
You now have a Nhost v2 project locally with correct migrations and metadata. Happy hacking!
|
||||
@@ -1,35 +0,0 @@
|
||||
---
|
||||
title: 'Welcome to Nhost'
|
||||
---
|
||||
|
||||
Nhost is an open-source, real-time, server-less backend platform for building reliable apps that scale with your business.
|
||||
|
||||
---
|
||||
|
||||
## Components
|
||||
|
||||
Nhost uses an opinionated set of open-source components.
|
||||
|
||||
#### Database
|
||||
|
||||
Your application gets its own PostgreSQL database, the world's most advanced relational database.
|
||||
|
||||
#### GraphQL API
|
||||
|
||||
Highly performant and real-time GraphQL API with Hasura.
|
||||
|
||||
#### Authentication and storage
|
||||
|
||||
User management & file storage seamlessly integrated with Hasura permissions.
|
||||
|
||||
#### Serverless functions
|
||||
|
||||
JavaScript and TypeScript functions run your custom code in the backend.
|
||||
|
||||
---
|
||||
|
||||
## Get started
|
||||
|
||||
Follow our [Quick start](/get-started/quick-start) guide to build your first app.
|
||||
|
||||
Check out [Nhost on GitHub](https://github.com/nhost/nhost). Give us a star, and feel free to open a discussion for any feature requests as well.
|
||||
@@ -16,6 +16,7 @@ Get started quickly by following one of our quickstart guides:
|
||||
|
||||
- [Next.js](/platform/quickstarts/nextjs)
|
||||
- [React](/platform/quickstarts/react)
|
||||
- [Vue](/platform/quickstarts/vue)
|
||||
|
||||
## Products and features
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
---
|
||||
title: 'Event triggers'
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
Event triggers are HTTP webhooks that fire on a database event, such as insert, update, or delete. These events are usually a result of GraphQL mutations, but any other database operation will also fire events.
|
||||
|
||||
**Example:** Imagine you want to send an email every time a user makes a new order in an e-commerce application. To achieve that, you would create an event trigger on **insert** for the **orders table**. Every time an order is created, an event trigger will send a webhook with the order information, and the webhook can send out an email to the customer.
|
||||
|
||||
---
|
||||
|
||||
## Creating event triggers
|
||||
|
||||
Event triggers are managed in Hasura. Go to Hasura, then select **Events** in the main menu and press "Create".
|
||||
|
||||

|
||||
|
||||
Nhost's [environment variables](/platform/environment-variables) can be used in event trigger headers. For example, you can attach `NHOST_WEBHOOK_SECRET` to an outgoing webhook here.
|
||||
|
||||
---
|
||||
|
||||
## Serverless functions
|
||||
|
||||
It's a common pattern to write a serverless function to catch a webhook fired by an event. When creating webhooks that are meant for your own serverless functions, use the following URL:
|
||||
|
||||
```bash
|
||||
https://[app-subdomain].nhost.run/v1/functions/my-endpoint
|
||||
```
|
||||
|
||||
The environment variable `NHOST_BACKEND_URL` will have the correct value.
|
||||
|
||||
```bash
|
||||
{{NHOST_BACKEND_URL}}/v1/functions/my-endpoint
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Security
|
||||
|
||||
In your serverless function, you need to make sure the request actually comes from your Hasura instance. To do this, you must do two things:
|
||||
|
||||
- Add the header `nhost-webhook-secret` when creating the event in Hasura. Set this to `NHOST_WEBHOOK_SECRET`.
|
||||
- Check the header in the serverless function. It should match the environment variable `NHOST_WEBHOOK_SECRET`.
|
||||
|
||||
```js
|
||||
export default async function handler(req, res) {
|
||||
|
||||
// Check webhook secret to make sure the request is valid
|
||||
if (
|
||||
req.headers['nhost-webhook-secret'] !== process.env.NHOST_WEBHOOK_SECRET
|
||||
) {
|
||||
return res.status(400).send('Incorrect webhook secret')
|
||||
}
|
||||
|
||||
// Do something
|
||||
// Example:
|
||||
// - Send an email
|
||||
// - Create a subscription in Stripe
|
||||
// - Generate a PDF
|
||||
// - Send a message to Slack or Discord
|
||||
// - Update some data in the database
|
||||
|
||||
console.log(JSON.stringify(req.body, null, 2))
|
||||
|
||||
return res.send('OK')
|
||||
}
|
||||
```
|
||||
88
docs/docs/platform/database/event-triggers.mdx
Normal file
88
docs/docs/platform/database/event-triggers.mdx
Normal file
@@ -0,0 +1,88 @@
|
||||
---
|
||||
title: 'Event triggers'
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
Event Triggers enable you to invoke webhooks when a database event happens. Event Triggers are typically used to do post-processing tasks, using custom backend code, based on database events.
|
||||
|
||||
Event Triggers are associated with a specific table in the database the following event types are available:
|
||||
|
||||
- **INSERT** - A row is inserted into a table
|
||||
- **UPDATE** - A row is updated in a table
|
||||
- **DELETE** - A row is deleted from a table
|
||||
|
||||
Event Triggers can also be triggered manually in the Hasura Console.
|
||||
|
||||
### Example Use Case
|
||||
|
||||
Let's say you're building an e-commerce application and you want to send an email to the customer when a new order is placed. Orders are stored in the `orders` table in your database.
|
||||
|
||||
To send out an email every time a new order is placed, you create an event trigger that listens for the `INSERT` event on the `orders` table. Now every time an order is placed, the even trigger invokes a webhook with the order information, and the webhook sends out the email.
|
||||
|
||||
## Create Event Trigger
|
||||
|
||||
Event Triggers are managed in the Hasura Console. Select **Events** in the main menu and click **Create** to add an Event Trigger.
|
||||
|
||||
<video width="99%" autoPlay muted loop controls="true">
|
||||
<source src="/videos/hasura-create-event-trigger.mp4" type="video/mp4" />
|
||||
</video>
|
||||
|
||||
## Event Triggers and Serverless Functions
|
||||
|
||||
Event Triggers and [Serverless Functions](/platform/serverless-functions) is a perfect combination to build powerful database-backend logic. Every Serverless Function is exposed as an HTTP endpoint that can be used as a webhook for your Event Triggers.
|
||||
|
||||
### Format
|
||||
|
||||
When using Serverless Functions as webhooks you should configure the webhook using a combination of environment variables and endpoints like this:
|
||||
|
||||
```
|
||||
{{NHOST_BACKEND_URL}}/v1/functions/orders-insert-send-email
|
||||
```
|
||||
|
||||

|
||||
|
||||
The `NHOST_BACKEND_URL` is a [system environment variable](/platform/environment-variables#system-environment-variables) and available in production and in development environments using the [CLI](/platform/cli).
|
||||
|
||||
### Security
|
||||
|
||||
To make sure incoming requests to your webhook comes from Hasura, and not some malicious third party, you can use a shared webhook secret between Hasura and your webhook handler (e.g. your Serverless Function).
|
||||
|
||||
It is recommended to use the `NHOST_WEBHOOK_SECRET`, which is a [system environment variable](/platform/environment-variables#system-environment-variables) and available in production and in development environments using the [CLI](/platform/cli). The `NHOST_WEBHOOK_SECRET` is available both in Hasura and in every Serverless Function.
|
||||
|
||||
To set this up is a two-step process:
|
||||
|
||||
- Step 1: Add the header `nhost-webhook-secret` with the value `NHOST_WEBHOOK_SECRET` (From env var) when creating the Event Trigger in the Hasura Console.
|
||||
|
||||

|
||||
|
||||
- Step 2: Check the header `nhost-webhook-secret` for incoming requests and make sure the header is the same as the environment variable `NHOST_WEBHOOK_SECRET`.
|
||||
|
||||
Here is an example of how to check the header in a Serverless Function:
|
||||
|
||||
```js
|
||||
export default async function handler(req, res) {
|
||||
// Check header to make sure the request comes from Hasura
|
||||
if (req.headers['nhost-webhook-secret'] !== process.env.NHOST_WEBHOOK_SECRET) {
|
||||
return res.status(400).send('Incorrect webhook secret')
|
||||
}
|
||||
|
||||
// Do something
|
||||
// Example:
|
||||
// - Send an email
|
||||
// - Create a subscription in Stripe
|
||||
// - Generate a PDF
|
||||
// - Send a message to Slack or Discord
|
||||
// - Update some data in the database
|
||||
|
||||
console.log(JSON.stringify(req.body, null, 2))
|
||||
|
||||
return res.send('OK')
|
||||
}
|
||||
```
|
||||
|
||||
The `NHOST_WEBHOOK_SECRET` is a [system environment variable](/platform/environment-variables#system-environment-variables) and available in production and in development environments using the [CLI](/platform/cli).
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Read the full [Event Triggers documentation from Hasura](https://hasura.io/docs/latest/graphql/core/event-triggers/index/).
|
||||
- Learn about the [GraphQL API](/platform/graphql).
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
title: 'Database'
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
Every Nhost app comes with a Postgres database. Postgres is the world's most advanced open-source relational database and the most popular SQL database among developers. The database is hosted with Amazon RDS.
|
||||
|
||||
Tables are managed in the Hasura Console.
|
||||
|
||||
---
|
||||
|
||||
## Creating tables
|
||||
|
||||
1. In Hasura Console, go to the **Data** tab, select the **public** schema in the left menu and click **Create Table**
|
||||
2. Enter a table name
|
||||
3. Add table columns
|
||||
4. Add a primary key (usually the ID column)
|
||||
5. (Optional) Add foreign keys
|
||||
6. (Optional) Add unique keys
|
||||
7. Click **Add Table**
|
||||
|
||||
When a table is created, the table is created in Postgres and added to your GraphQL API.
|
||||
|
||||
#### Schemas
|
||||
|
||||
You should use the `public` schema when developing your app. `auth` and `storage` are reserved for system functionality like user and file management. You are allowed to modify permissions for tables in the `auth` and `storage` schemas, however.
|
||||
|
||||
---
|
||||
|
||||
## Modifying table schema
|
||||
|
||||
1. In Hasura Console, go to the **Data** tab and click on the table you want to edit in the left menu
|
||||
2. Click **Modify**
|
||||
3. Modify or add table columns
|
||||
|
||||
#### Track foreign-key relations
|
||||
|
||||
1. Click on Data in the top menu.
|
||||
2. A list of untracked foreign-key relations is presented.
|
||||
3. Click Track All (recommended) or click Track for each relationship you want to track.
|
||||
|
||||
---
|
||||
|
||||
## Deleting tables
|
||||
|
||||
1. In Hasura Console, go to the **Data** tab and select the table you want to delete in the left menu
|
||||
2. Click **Modify**
|
||||
3. Scroll to the bottom of the page and click **Delete table** to open the confirmation dialog
|
||||
143
docs/docs/platform/database/index.mdx
Normal file
143
docs/docs/platform/database/index.mdx
Normal file
@@ -0,0 +1,143 @@
|
||||
---
|
||||
title: 'Database'
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs'
|
||||
import TabItem from '@theme/TabItem'
|
||||
|
||||
Every Nhost app comes with its own [Postgres database](https://postgres.org/). Postgres is the world's most advanced open-source relational database and it's the most [popular SQL database for developers](https://insights.stackoverflow.com/survey/2021#section-most-loved-dreaded-and-wanted-databases).
|
||||
|
||||
:::info
|
||||
|
||||
It's currently not possible to connect directly to the Postgres database via a connection string. We're working on making the database available soon. You can follow [this issue on GitHub](https://github.com/nhost/nhost/issues/113).
|
||||
|
||||
:::
|
||||
|
||||
The database is managed via the Hasura Console where you can manage the database via an intuative UI. You can also use SQL to directly interact with the database via the Hasura Console.
|
||||
|
||||
## Hasura Console
|
||||
|
||||
Hasura Console is where you manage your database. This is where you create and manage tables, schemas, and data.
|
||||
|
||||
Open the Hasura Console by clicking on **Data** in the top menu in the Nhost Dashboard, copy the **admin secret**, and click **Open Hasura**. Use the **admin secret** to sign in.
|
||||
|
||||
<video width="99%" autoPlay muted loop controls="true">
|
||||
<source src="/videos/open-hasura-console.mp4" type="video/mp4" />
|
||||
</video>
|
||||
|
||||
## Schemas
|
||||
|
||||
The two schemas `auth` and `storage` are reserved for Nhost Auth and Nhost Storage to work. You're allowed to modify **permissions** and **add relationships**. However, never modify any tables or remove relationships that were added by Nhost inside the `auth` and `storage` schemas.
|
||||
|
||||
Generally, you should use the `public` schema when creating and managing your tables for your app. It's also ok to add custom schemas for more advanced usage.
|
||||
|
||||
## Create Table
|
||||
|
||||
1. In Hasura Console, go to the **Data** tab, select the **public** schema in the left menu and click **Create Table**.
|
||||
2. Enter a table name.
|
||||
3. Add table columns.
|
||||
4. Add a primary key (usually the ID column).
|
||||
5. (Optional) Add foreign keys.
|
||||
6. (Optional) Add unique keys.
|
||||
7. Click **Add Table**.
|
||||
|
||||
When a table is created the table is instantly available through the [GraphQL API](/platform/graphql).
|
||||
|
||||
Here's an example of how to create a `customers` table:
|
||||
|
||||
<Tabs groupId="hasura-console-vs-sql">
|
||||
<TabItem value="hasura-cosnole" label="Hasura Console" default>
|
||||
|
||||
<video width="99%" autoPlay muted loop controls="true">
|
||||
<source src="/videos/hasura-create-table.mp4" type="video/mp4" />
|
||||
</video>
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="sql" label="SQL">
|
||||
|
||||
```sql
|
||||
CREATE TABLE "public"."customers" (
|
||||
"id" serial NOT NULL PRIMARY KEY,
|
||||
"name" text NOT NULL
|
||||
);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Modify Table
|
||||
|
||||
1. In Hasura Console, go to the **Data** tab and click on the table you want to edit in the left menu.
|
||||
2. Click **Modify**.
|
||||
3. Modify or add table columns.
|
||||
|
||||
Here's an example of how to modify a `customers` table by adding an `address` column:
|
||||
|
||||
<Tabs groupId="hasura-console-vs-sql">
|
||||
<TabItem value="hasura-cosnole" label="Hasura Console" default>
|
||||
|
||||
<video width="99%" autoPlay muted loop controls="true">
|
||||
<source src="/videos/hasura-modify-table.mp4" type="video/mp4" />
|
||||
</video>
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="sql" label="SQL">
|
||||
|
||||
```sql
|
||||
ALTER TABLE "public"."customers" ADD COLUMN "address" text;
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Delete Table
|
||||
|
||||
1. In Hasura Console, go to the **Data** tab and select the table you want to delete in the left menu.
|
||||
2. Click **Modify**.
|
||||
3. Scroll to the bottom of the page and click **Delete table** to open the confirmation dialog.
|
||||
4. Type the **name of the table** and click OK.
|
||||
|
||||
Here's an example of how to delete a `customers` table:
|
||||
|
||||
<Tabs groupId="hasura-console-vs-sql">
|
||||
<TabItem value="hasura-cosnole" label="Hasura Console" default>
|
||||
|
||||
<video width="99%" autoPlay muted loop controls="true">
|
||||
<source src="/videos/hasura-delete-table.mp4" type="video/mp4" />
|
||||
</video>
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="sql" label="SQL">
|
||||
|
||||
```sql
|
||||
DROP TABLE "public"."customers";
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Migrations
|
||||
|
||||
To track database changes, use the [Nhost CLI](/platform/cli) to develop locally and use our [GitHub integration](/platform/github-integration) to automatically deploy database migrations live.
|
||||
|
||||
1. Develop locally using the Nhost CLI.
|
||||
2. Push changes to GitHub.
|
||||
3. Nhost automatically deploys changes.
|
||||
|
||||
Learn how to [get started with Nhost CLI](/platform/overview/get-started-with-nhost-cli).
|
||||
|
||||
## Backups
|
||||
|
||||
Databases on [Pro and Enterprise plans](https://nhost.io/pricing) are backed up automatically.
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Use lower-case names for tables. E.g. `customers` instead of `Customers`.
|
||||
- Use plural names for tables. E.g. `customers` instead of `customer`.
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Learn PostgreSQL Tutorial - Full Course for Beginners (YouTube)](https://www.youtube.com/watch?v=qw--VYLpxG4).
|
||||
- Learn more about how to manage your [Postgres database in Hasura](https://hasura.io/docs/latest/graphql/core/databases/postgres/schema/index/).
|
||||
- Learn about the [GraphQL API](/platform/graphql).
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"label": "Overview",
|
||||
"position": 2,
|
||||
"collapsed": false
|
||||
"collapsed": true
|
||||
}
|
||||
|
||||
@@ -100,20 +100,9 @@ nhost logout
|
||||
|
||||
### 1. Create a new Nhost app
|
||||
|
||||
First things first, we need to create a new Nhost project.
|
||||
import CreateApp from '@site/src/components/create-nhost-app.mdx';
|
||||
|
||||
So, log in to your Nhost dashboard and click the **Create your first app**
|
||||
button.
|
||||
|
||||

|
||||
|
||||
Next, give your new Nhost app a name, select a geographic region for your Nhost
|
||||
services and click **Create App**.
|
||||
|
||||

|
||||
|
||||
After a few seconds, you should get a PostgreSQL database, a GraphQL API with
|
||||
Hasura, file storage, and authentication set up.
|
||||
<CreateApp />
|
||||
|
||||
### 2. Create a new GitHub Repository
|
||||
|
||||
@@ -368,13 +357,11 @@ Then, create a new file named `time.ts` inside the `functions/` folder of your
|
||||
working directory, and paste the following code:
|
||||
|
||||
```ts title="functions/time.ts"
|
||||
import { Request, Response } from 'express';
|
||||
import { Request, Response } from 'express'
|
||||
|
||||
export default (req: Request, res: Response) => {
|
||||
return res
|
||||
.status(200)
|
||||
.send(`Hello ${req.query.name}! It's now: ${new Date().toUTCString()}`);
|
||||
};
|
||||
return res.status(200).send(`Hello ${req.query.name}! It's now: ${new Date().toUTCString()}`)
|
||||
}
|
||||
```
|
||||
|
||||
Every JavaScript and TypeScript file inside the `functions/` folder becomes an
|
||||
|
||||
@@ -3,8 +3,8 @@ title: 'Quickstart: Next.js'
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Tabs from '@theme/Tabs'
|
||||
import TabItem from '@theme/TabItem'
|
||||
|
||||
# Quickstart: Next.js
|
||||
|
||||
@@ -32,20 +32,9 @@ You'll need **Node.js** version 12 or later: [install it from here](https://node
|
||||
|
||||
### Create a new Nhost app
|
||||
|
||||
First things first, we need to create a new Nhost project.
|
||||
import CreateApp from '@site/src/components/create-nhost-app.mdx'
|
||||
|
||||
So, log in to your Nhost dashboard and click the **Create your first app**
|
||||
button.
|
||||
|
||||

|
||||
|
||||
Next, give your new Nhost app a name, select a geographic region for your Nhost
|
||||
services and click **Create App**.
|
||||
|
||||

|
||||
|
||||
After a few seconds, you should get a PostgreSQL database, a GraphQL API with
|
||||
Hasura, file storage, and authentication set up.
|
||||
<CreateApp />
|
||||
|
||||
:::info
|
||||
You can also connect your Nhost app to a GitHub repository. When you do this, any updates you push to your code will automatically be deployed. [Learn more](https://docs.nhost.io/platform/github-integration).
|
||||
@@ -191,50 +180,44 @@ So, open up the corresponding file from your project, and use the following
|
||||
code:
|
||||
|
||||
```jsx title="components/SignUp.js"
|
||||
import styles from '../styles/components/SignUp.module.css';
|
||||
import { useState } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useSignUpEmailPassword } from '@nhost/nextjs';
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import Input from './Input';
|
||||
import Spinner from './Spinner';
|
||||
import styles from '../styles/components/SignUp.module.css'
|
||||
import { useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useSignUpEmailPassword } from '@nhost/nextjs'
|
||||
import Link from 'next/link'
|
||||
import Image from 'next/image'
|
||||
import Input from './Input'
|
||||
import Spinner from './Spinner'
|
||||
|
||||
const SignUp = () => {
|
||||
const [firstName, setFirstName] = useState('');
|
||||
const [lastName, setLastName] = useState('');
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [firstName, setFirstName] = useState('')
|
||||
const [lastName, setLastName] = useState('')
|
||||
const [email, setEmail] = useState('')
|
||||
const [password, setPassword] = useState('')
|
||||
|
||||
const router = useRouter();
|
||||
const router = useRouter()
|
||||
|
||||
const {
|
||||
signUpEmailPassword,
|
||||
isLoading,
|
||||
isSuccess,
|
||||
needsEmailVerification,
|
||||
isError,
|
||||
error,
|
||||
} = useSignUpEmailPassword();
|
||||
const { signUpEmailPassword, isLoading, isSuccess, needsEmailVerification, isError, error } =
|
||||
useSignUpEmailPassword()
|
||||
|
||||
const handleOnSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
e.preventDefault()
|
||||
|
||||
await signUpEmailPassword(email, password, {
|
||||
displayName: `${firstName} ${lastName}`.trim(),
|
||||
metadata: {
|
||||
firstName,
|
||||
lastName,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
if (isSuccess) {
|
||||
router.push('/');
|
||||
return null;
|
||||
lastName
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const disableForm = isLoading || needsEmailVerification;
|
||||
if (isSuccess) {
|
||||
router.push('/')
|
||||
return null
|
||||
}
|
||||
|
||||
const disableForm = isLoading || needsEmailVerification
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
@@ -245,8 +228,7 @@ const SignUp = () => {
|
||||
|
||||
{needsEmailVerification ? (
|
||||
<p className={styles['verification-text']}>
|
||||
Please check your mailbox and follow the verification link to verify
|
||||
your email.
|
||||
Please check your mailbox and follow the verification link to verify your email.
|
||||
</p>
|
||||
) : (
|
||||
<form onSubmit={handleOnSubmit} className={styles.form}>
|
||||
@@ -283,17 +265,11 @@ const SignUp = () => {
|
||||
required
|
||||
/>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={disableForm}
|
||||
className={styles.button}
|
||||
>
|
||||
<button type="submit" disabled={disableForm} className={styles.button}>
|
||||
{isLoading ? <Spinner size="sm" /> : 'Create account'}
|
||||
</button>
|
||||
|
||||
{isError ? (
|
||||
<p className={styles['error-text']}>{error?.message}</p>
|
||||
) : null}
|
||||
{isError ? <p className={styles['error-text']}>{error?.message}</p> : null}
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
@@ -305,10 +281,10 @@ const SignUp = () => {
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default SignUp;
|
||||
export default SignUp
|
||||
```
|
||||
|
||||
By default, the user must verify his email address before fully signing up. You can change this setting from your Nhost dashboard.
|
||||
@@ -324,41 +300,35 @@ what your component should look like after applying the changes for the sign-in
|
||||
logic:
|
||||
|
||||
```jsx title="components/SignIn.js"
|
||||
import styles from '../styles/components/SignIn.module.css';
|
||||
import { useState } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useSignInEmailPassword } from '@nhost/nextjs';
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import Input from './Input';
|
||||
import Spinner from './Spinner';
|
||||
import styles from '../styles/components/SignIn.module.css'
|
||||
import { useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useSignInEmailPassword } from '@nhost/nextjs'
|
||||
import Link from 'next/link'
|
||||
import Image from 'next/image'
|
||||
import Input from './Input'
|
||||
import Spinner from './Spinner'
|
||||
|
||||
const SignIn = () => {
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [email, setEmail] = useState('')
|
||||
const [password, setPassword] = useState('')
|
||||
|
||||
const router = useRouter();
|
||||
const router = useRouter()
|
||||
|
||||
const {
|
||||
signInEmailPassword,
|
||||
isLoading,
|
||||
isSuccess,
|
||||
needsEmailVerification,
|
||||
isError,
|
||||
error,
|
||||
} = useSignInEmailPassword();
|
||||
const { signInEmailPassword, isLoading, isSuccess, needsEmailVerification, isError, error } =
|
||||
useSignInEmailPassword()
|
||||
|
||||
const handleOnSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
await signInEmailPassword(email, password);
|
||||
};
|
||||
|
||||
if (isSuccess) {
|
||||
router.push('/');
|
||||
return null;
|
||||
e.preventDefault()
|
||||
await signInEmailPassword(email, password)
|
||||
}
|
||||
|
||||
const disableForm = isLoading || needsEmailVerification;
|
||||
if (isSuccess) {
|
||||
router.push('/')
|
||||
return null
|
||||
}
|
||||
|
||||
const disableForm = isLoading || needsEmailVerification
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
@@ -369,8 +339,7 @@ const SignIn = () => {
|
||||
|
||||
{needsEmailVerification ? (
|
||||
<p className={styles['verification-text']}>
|
||||
Please check your mailbox and follow the verification link to verify
|
||||
your email.
|
||||
Please check your mailbox and follow the verification link to verify your email.
|
||||
</p>
|
||||
) : (
|
||||
<>
|
||||
@@ -392,17 +361,11 @@ const SignIn = () => {
|
||||
required
|
||||
/>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={disableForm}
|
||||
className={styles.button}
|
||||
>
|
||||
<button type="submit" disabled={disableForm} className={styles.button}>
|
||||
{isLoading ? <Spinner size="sm" /> : 'Sign in'}
|
||||
</button>
|
||||
|
||||
{isError ? (
|
||||
<p className={styles['error-text']}>{error?.message}</p>
|
||||
) : null}
|
||||
{isError ? <p className={styles['error-text']}>{error?.message}</p> : null}
|
||||
</form>
|
||||
</>
|
||||
)}
|
||||
@@ -415,10 +378,10 @@ const SignIn = () => {
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default SignIn;
|
||||
export default SignIn
|
||||
```
|
||||
|
||||
#### 3. Sign-out
|
||||
@@ -427,22 +390,22 @@ Finally, to allow the users to sign out from the app, we can use the Nhost
|
||||
`useSignOut` hook:
|
||||
|
||||
```jsx title="components/Layout.js"
|
||||
import { useSignOut } from '@nhost/nextjs';
|
||||
import { useSignOut } from '@nhost/nextjs'
|
||||
|
||||
const Layout = ({ children = null }) => {
|
||||
const { signOut } = useSignOut();
|
||||
const { signOut } = useSignOut()
|
||||
|
||||
const menuItems = [
|
||||
//..
|
||||
{
|
||||
label: 'Logout',
|
||||
onClick: signOut,
|
||||
icon: LogoutIcon,
|
||||
},
|
||||
];
|
||||
icon: LogoutIcon
|
||||
}
|
||||
]
|
||||
|
||||
//...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Protect routes
|
||||
@@ -459,31 +422,31 @@ Nhost SDK by creating a
|
||||
[high-order component](https://reactjs.org/docs/higher-order-components.html):
|
||||
|
||||
```jsx title="withAuth.js"
|
||||
import styles from './styles/pages/ProtectedRoute.module.css';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useAuthenticationStatus } from '@nhost/nextjs';
|
||||
import Spinner from './components/Spinner';
|
||||
import styles from './styles/pages/ProtectedRoute.module.css'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useAuthenticationStatus } from '@nhost/nextjs'
|
||||
import Spinner from './components/Spinner'
|
||||
|
||||
export default function withAuth(Component) {
|
||||
return function AuthProtected(props) {
|
||||
const router = useRouter();
|
||||
const { isLoading, isAuthenticated } = useAuthenticationStatus();
|
||||
const router = useRouter()
|
||||
const { isLoading, isAuthenticated } = useAuthenticationStatus()
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<Spinner />
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
if (!isAuthenticated) {
|
||||
router.push('/sign-in');
|
||||
return null;
|
||||
router.push('/sign-in')
|
||||
return null
|
||||
}
|
||||
|
||||
return <Component {...props} />;
|
||||
};
|
||||
return <Component {...props} />
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -498,26 +461,26 @@ values={[
|
||||
<TabItem value="index">
|
||||
|
||||
```js
|
||||
import withAuth from '../withAuth';
|
||||
import withAuth from '../withAuth'
|
||||
|
||||
const Home = () => {
|
||||
//...
|
||||
};
|
||||
}
|
||||
|
||||
export default withAuth(Home);
|
||||
export default withAuth(Home)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="profile">
|
||||
|
||||
```js
|
||||
import withAuth from '../withAuth';
|
||||
import withAuth from '../withAuth'
|
||||
|
||||
const Profile = () => {
|
||||
//...
|
||||
};
|
||||
}
|
||||
|
||||
export default withAuth(Profile);
|
||||
export default withAuth(Profile)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
@@ -534,22 +497,20 @@ can use the `useUserData` hook provided by Nhost to do it.
|
||||
So, open the `UserProvider.js` file and use this hook like so:
|
||||
|
||||
```js
|
||||
import React, { useContext } from 'react';
|
||||
import React, { useContext } from 'react'
|
||||
// highlight-next-line
|
||||
import { useUserData } from '@nhost/nextjs';
|
||||
import { useUserData } from '@nhost/nextjs'
|
||||
|
||||
const UserContext = React.createContext(null);
|
||||
const UserContext = React.createContext(null)
|
||||
|
||||
export function UserProvider({ children = null }) {
|
||||
// highlight-next-line
|
||||
const user = useUserData();
|
||||
return (
|
||||
<UserContext.Provider value={{ user }}>{children}</UserContext.Provider>
|
||||
);
|
||||
const user = useUserData()
|
||||
return <UserContext.Provider value={{ user }}>{children}</UserContext.Provider>
|
||||
}
|
||||
|
||||
export function useUserContext() {
|
||||
return useContext(UserContext);
|
||||
return useContext(UserContext)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -589,14 +550,14 @@ Then, add the `NhostApolloProvider` from `@nhost/react-apollo` into your
|
||||
`_app_.js` file.
|
||||
|
||||
```jsx title="pages/_app.js"
|
||||
import { NhostApolloProvider } from '@nhost/react-apollo';
|
||||
import { NhostApolloProvider } from '@nhost/react-apollo'
|
||||
|
||||
function MyApp({ Component, pageProps }) {
|
||||
return (
|
||||
<NhostNextProvider nhost={nhost} initial={pageProps.nhostSession}>
|
||||
<NhostApolloProvider nhost={nhost}>{/* ... */}</NhostApolloProvider>
|
||||
</NhostNextProvider>
|
||||
);
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -604,28 +565,24 @@ From there, we can construct our GraphQL query and use the Apollo `useMutation`
|
||||
hook to execute that query when the user submits the form from the profile page:
|
||||
|
||||
```js title="pages/profile.js"
|
||||
import { gql, useMutation } from '@apollo/client';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import { gql, useMutation } from '@apollo/client'
|
||||
import { toast } from 'react-hot-toast'
|
||||
|
||||
const UPDATE_USER_MUTATION = gql`
|
||||
mutation ($id: uuid!, $displayName: String!, $metadata: jsonb) {
|
||||
updateUser(
|
||||
pk_columns: { id: $id }
|
||||
_set: { displayName: $displayName, metadata: $metadata }
|
||||
) {
|
||||
updateUser(pk_columns: { id: $id }, _set: { displayName: $displayName, metadata: $metadata }) {
|
||||
id
|
||||
displayName
|
||||
metadata
|
||||
}
|
||||
}
|
||||
`;
|
||||
`
|
||||
|
||||
const Profile = () => {
|
||||
const [mutateUser, { loading: updatingProfile }] =
|
||||
useMutation(UPDATE_USER_MUTATION);
|
||||
const [mutateUser, { loading: updatingProfile }] = useMutation(UPDATE_USER_MUTATION)
|
||||
|
||||
const updateUserProfile = async (e) => {
|
||||
e.preventDefault();
|
||||
e.preventDefault()
|
||||
|
||||
try {
|
||||
await mutateUser({
|
||||
@@ -634,18 +591,18 @@ const Profile = () => {
|
||||
displayName: `${firstName} ${lastName}`.trim(),
|
||||
metadata: {
|
||||
firstName,
|
||||
lastName,
|
||||
},
|
||||
},
|
||||
});
|
||||
toast.success('Updated successfully', { id: 'updateProfile' });
|
||||
lastName
|
||||
}
|
||||
}
|
||||
})
|
||||
toast.success('Updated successfully', { id: 'updateProfile' })
|
||||
} catch (error) {
|
||||
toast.error('Unable to update profile', { id: 'updateProfile' });
|
||||
toast.error('Unable to update profile', { id: 'updateProfile' })
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Finally, since Hasura has an **allow nothing by default** policy, and we haven't
|
||||
@@ -675,7 +632,7 @@ Finally, to add caching, synchronizing, and updating server state in your Next.j
|
||||
So, first add the following GraphQL query to retrieve the current user data from the `UserProvider.js` file:
|
||||
|
||||
```js title="UserProvider.js"
|
||||
import { gql } from '@apollo/client';
|
||||
import { gql } from '@apollo/client'
|
||||
|
||||
const GET_USER_QUERY = gql`
|
||||
query GetUser($id: uuid!) {
|
||||
@@ -687,7 +644,7 @@ const GET_USER_QUERY = gql`
|
||||
avatarUrl
|
||||
}
|
||||
}
|
||||
`;
|
||||
`
|
||||
|
||||
export function UserProvider() {
|
||||
//...
|
||||
@@ -697,10 +654,10 @@ export function UserProvider() {
|
||||
Then, replace the `useUserData` hook with the `useUserId` hook to retrieve the current user's ID only.
|
||||
|
||||
```js title="UserProvider.js"
|
||||
import { useUserId } from '@nhost/nextjs';
|
||||
import { useUserId } from '@nhost/nextjs'
|
||||
|
||||
export function UserProvider() {
|
||||
const id = useUserId();
|
||||
const id = useUserId()
|
||||
//...
|
||||
}
|
||||
```
|
||||
@@ -709,29 +666,27 @@ Finally, we can run our GraphQL query using the `useQuery` hook and the current
|
||||
|
||||
```jsx title="UserProvider.js"
|
||||
// highlight-next-line
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
import { gql, useQuery } from '@apollo/client'
|
||||
|
||||
export function UserProvider({ children = null }) {
|
||||
const id = useUserId();
|
||||
const id = useUserId()
|
||||
// highlight-start
|
||||
const { loading, error, data } = useQuery(GET_USER_QUERY, {
|
||||
variables: { id },
|
||||
});
|
||||
const user = data?.user;
|
||||
variables: { id }
|
||||
})
|
||||
const user = data?.user
|
||||
// highlight-end
|
||||
|
||||
// highlight-start
|
||||
if (error) {
|
||||
return <p>Something went wrong. Try to refresh the page.</p>;
|
||||
return <p>Something went wrong. Try to refresh the page.</p>
|
||||
}
|
||||
if (loading) {
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
// highlight-end
|
||||
|
||||
return (
|
||||
<UserContext.Provider value={{ user }}>{children}</UserContext.Provider>
|
||||
);
|
||||
return <UserContext.Provider value={{ user }}>{children}</UserContext.Provider>
|
||||
}
|
||||
```
|
||||
|
||||
@@ -741,4 +696,4 @@ You now have a fully functional Next.js application. Congratulations!
|
||||
|
||||
- Did you enjoy Nhost? Give us a star ⭐ on [Github](https://github.com/nhost/nhost). Thank you!
|
||||
- Check out our more in-depth [examples](https://github.com/nhost/nhost/tree/main/examples).
|
||||
- Build your next app with [Nhost](https://app.nhost.io/)!
|
||||
- Build your next app with [Nhost](https://app.nhost.io/)!
|
||||
|
||||
@@ -3,8 +3,8 @@ title: 'Quickstart: React'
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Tabs from '@theme/Tabs'
|
||||
import TabItem from '@theme/TabItem'
|
||||
|
||||
# Quickstart: React
|
||||
|
||||
@@ -32,21 +32,9 @@ You'll need **Node.js** version 14 or later: [install it from here](https://node
|
||||
|
||||
### Create a new Nhost app
|
||||
|
||||
First things first, we need to create a new Nhost project.
|
||||
|
||||
So, log in to your Nhost dashboard and click the **Create your first app**
|
||||
button.
|
||||
|
||||

|
||||
|
||||
Next, give your new Nhost app a name, select a geographic region for your Nhost
|
||||
services and click **Create App**.
|
||||
|
||||

|
||||
|
||||
After a few seconds, you should get a PostgreSQL database, a GraphQL API with
|
||||
Hasura, file storage, and authentication set up.
|
||||
import CreateApp from '@site/src/components/create-nhost-app.mdx'
|
||||
|
||||
<CreateApp />
|
||||
:::info
|
||||
You can also connect your Nhost app to a GitHub repository. When you do this, any updates you push to your code will automatically be deployed. [Learn more](https://docs.nhost.io/platform/github-integration).
|
||||
:::
|
||||
@@ -135,21 +123,21 @@ Use the following code to instantiate a new Nhost client and link it to your
|
||||
Nhost backend:
|
||||
|
||||
```jsx title="src/App.js"
|
||||
import { NhostClient, NhostReactProvider } from '@nhost/react';
|
||||
import { NhostClient, NhostReactProvider } from '@nhost/react'
|
||||
|
||||
const nhost = new NhostClient({
|
||||
backendUrl: process.env.REACT_APP_NHOST_BACKEND_URL || '',
|
||||
});
|
||||
backendUrl: process.env.REACT_APP_NHOST_BACKEND_URL || ''
|
||||
})
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<NhostReactProvider nhost={nhost}>
|
||||
<BrowserRouter>{/* ... */}</BrowserRouter>
|
||||
</NhostReactProvider>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
export default App;
|
||||
export default App
|
||||
```
|
||||
|
||||
Finally, make sure to create an environment variable named
|
||||
@@ -184,45 +172,39 @@ So, open up the corresponding file from your project, and use the following
|
||||
code:
|
||||
|
||||
```jsx title="src/components/SignUp.js"
|
||||
import styles from '../styles/components/SignUp.module.css';
|
||||
import { useState } from 'react';
|
||||
import { useSignUpEmailPassword } from '@nhost/react';
|
||||
import { Link, Navigate } from 'react-router-dom';
|
||||
import Input from './Input';
|
||||
import Spinner from './Spinner';
|
||||
import styles from '../styles/components/SignUp.module.css'
|
||||
import { useState } from 'react'
|
||||
import { useSignUpEmailPassword } from '@nhost/react'
|
||||
import { Link, Navigate } from 'react-router-dom'
|
||||
import Input from './Input'
|
||||
import Spinner from './Spinner'
|
||||
|
||||
const SignUp = () => {
|
||||
const [firstName, setFirstName] = useState('');
|
||||
const [lastName, setLastName] = useState('');
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [firstName, setFirstName] = useState('')
|
||||
const [lastName, setLastName] = useState('')
|
||||
const [email, setEmail] = useState('')
|
||||
const [password, setPassword] = useState('')
|
||||
|
||||
const {
|
||||
signUpEmailPassword,
|
||||
isLoading,
|
||||
isSuccess,
|
||||
needsEmailVerification,
|
||||
isError,
|
||||
error,
|
||||
} = useSignUpEmailPassword();
|
||||
const { signUpEmailPassword, isLoading, isSuccess, needsEmailVerification, isError, error } =
|
||||
useSignUpEmailPassword()
|
||||
|
||||
const handleOnSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
e.preventDefault()
|
||||
|
||||
signUpEmailPassword(email, password, {
|
||||
displayName: `${firstName} ${lastName}`.trim(),
|
||||
metadata: {
|
||||
firstName,
|
||||
lastName,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
if (isSuccess) {
|
||||
return <Navigate to="/" replace={true} />;
|
||||
lastName
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const disableForm = isLoading || needsEmailVerification;
|
||||
if (isSuccess) {
|
||||
return <Navigate to="/" replace={true} />
|
||||
}
|
||||
|
||||
const disableForm = isLoading || needsEmailVerification
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
@@ -233,8 +215,7 @@ const SignUp = () => {
|
||||
|
||||
{needsEmailVerification ? (
|
||||
<p className={styles['verification-text']}>
|
||||
Please check your mailbox and follow the verification link to verify
|
||||
your email.
|
||||
Please check your mailbox and follow the verification link to verify your email.
|
||||
</p>
|
||||
) : (
|
||||
<form onSubmit={handleOnSubmit} className={styles.form}>
|
||||
@@ -271,17 +252,11 @@ const SignUp = () => {
|
||||
required
|
||||
/>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={disableForm}
|
||||
className={styles.button}
|
||||
>
|
||||
<button type="submit" disabled={disableForm} className={styles.button}>
|
||||
{isLoading ? <Spinner size="sm" /> : 'Create account'}
|
||||
</button>
|
||||
|
||||
{isError ? (
|
||||
<p className={styles['error-text']}>{error?.message}</p>
|
||||
) : null}
|
||||
{isError ? <p className={styles['error-text']}>{error?.message}</p> : null}
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
@@ -293,10 +268,10 @@ const SignUp = () => {
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default SignUp;
|
||||
export default SignUp
|
||||
```
|
||||
|
||||
By default, the user must verify his email address before fully signing up. You can change this setting from your Nhost dashboard.
|
||||
@@ -312,36 +287,30 @@ what your component should look like after applying the changes for the sign-in
|
||||
logic:
|
||||
|
||||
```jsx title="src/components/SignIn.js"
|
||||
import styles from '../styles/components/SignIn.module.css';
|
||||
import { useState } from 'react';
|
||||
import { useSignInEmailPassword } from '@nhost/react';
|
||||
import { Link, Navigate } from 'react-router-dom';
|
||||
import Input from './Input';
|
||||
import Spinner from './Spinner';
|
||||
import styles from '../styles/components/SignIn.module.css'
|
||||
import { useState } from 'react'
|
||||
import { useSignInEmailPassword } from '@nhost/react'
|
||||
import { Link, Navigate } from 'react-router-dom'
|
||||
import Input from './Input'
|
||||
import Spinner from './Spinner'
|
||||
|
||||
const SignIn = () => {
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [email, setEmail] = useState('')
|
||||
const [password, setPassword] = useState('')
|
||||
|
||||
const {
|
||||
signInEmailPassword,
|
||||
isLoading,
|
||||
isSuccess,
|
||||
needsEmailVerification,
|
||||
isError,
|
||||
error,
|
||||
} = useSignInEmailPassword();
|
||||
const { signInEmailPassword, isLoading, isSuccess, needsEmailVerification, isError, error } =
|
||||
useSignInEmailPassword()
|
||||
|
||||
const handleOnSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
signInEmailPassword(email, password);
|
||||
};
|
||||
|
||||
if (isSuccess) {
|
||||
return <Navigate to="/" replace={true} />;
|
||||
e.preventDefault()
|
||||
signInEmailPassword(email, password)
|
||||
}
|
||||
|
||||
const disableForm = isLoading || needsEmailVerification;
|
||||
if (isSuccess) {
|
||||
return <Navigate to="/" replace={true} />
|
||||
}
|
||||
|
||||
const disableForm = isLoading || needsEmailVerification
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
@@ -352,8 +321,7 @@ const SignIn = () => {
|
||||
|
||||
{needsEmailVerification ? (
|
||||
<p className={styles['verification-text']}>
|
||||
Please check your mailbox and follow the verification link to verify
|
||||
your email.
|
||||
Please check your mailbox and follow the verification link to verify your email.
|
||||
</p>
|
||||
) : (
|
||||
<form onSubmit={handleOnSubmit} className={styles.form}>
|
||||
@@ -374,17 +342,11 @@ const SignIn = () => {
|
||||
required
|
||||
/>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={disableForm}
|
||||
className={styles.button}
|
||||
>
|
||||
<button type="submit" disabled={disableForm} className={styles.button}>
|
||||
{isLoading ? <Spinner size="sm" /> : 'Sign in'}
|
||||
</button>
|
||||
|
||||
{isError ? (
|
||||
<p className={styles['error-text']}>{error?.message}</p>
|
||||
) : null}
|
||||
{isError ? <p className={styles['error-text']}>{error?.message}</p> : null}
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
@@ -396,10 +358,10 @@ const SignIn = () => {
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default SignIn;
|
||||
export default SignIn
|
||||
```
|
||||
|
||||
#### 3. Sign-out
|
||||
@@ -408,22 +370,22 @@ Finally, to allow the users to sign out from the app, we can use the Nhost
|
||||
`useSignOut` hook:
|
||||
|
||||
```jsx title="src/components/Layout.js"
|
||||
import { useSignOut } from '@nhost/react';
|
||||
import { useSignOut } from '@nhost/react'
|
||||
|
||||
const Layout = () => {
|
||||
const { signOut } = useSignOut();
|
||||
const { signOut } = useSignOut()
|
||||
|
||||
const menuItems = [
|
||||
//..
|
||||
{
|
||||
label: 'Logout',
|
||||
onClick: signOut,
|
||||
icon: LogoutIcon,
|
||||
},
|
||||
];
|
||||
icon: LogoutIcon
|
||||
}
|
||||
]
|
||||
|
||||
//...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Protect routes
|
||||
@@ -438,37 +400,37 @@ page if they try to access those routes.
|
||||
To do so, we can create a wrapper component (`ProtectedRoute`) to check the authentication status of the current user using the Nhost SDK:
|
||||
|
||||
```jsx title="src/components/ProtectedRoute.js"
|
||||
import styles from '../styles/components/ProtectedRoute.module.css';
|
||||
import { useAuthenticationStatus } from '@nhost/react';
|
||||
import { Navigate, useLocation } from 'react-router-dom';
|
||||
import Spinner from './Spinner';
|
||||
import styles from '../styles/components/ProtectedRoute.module.css'
|
||||
import { useAuthenticationStatus } from '@nhost/react'
|
||||
import { Navigate, useLocation } from 'react-router-dom'
|
||||
import Spinner from './Spinner'
|
||||
|
||||
const ProtectedRoute = ({ children }) => {
|
||||
const { isAuthenticated, isLoading } = useAuthenticationStatus();
|
||||
const location = useLocation();
|
||||
const { isAuthenticated, isLoading } = useAuthenticationStatus()
|
||||
const location = useLocation()
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<Spinner />
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
if (!isAuthenticated) {
|
||||
return <Navigate to="/sign-in" state={{ from: location }} replace />;
|
||||
return <Navigate to="/sign-in" state={{ from: location }} replace />
|
||||
}
|
||||
|
||||
return children;
|
||||
};
|
||||
return children
|
||||
}
|
||||
|
||||
export default ProtectedRoute;
|
||||
export default ProtectedRoute
|
||||
```
|
||||
|
||||
Then, we can use a [layout route](https://reactrouter.com/docs/en/v6/getting-started/concepts#layout-routes) in our `App.js` file, to wrap the `ProtectedRoute` component around the routes we want to protect:
|
||||
|
||||
```jsx title="src/App.js"
|
||||
import ProtectedRoute from './components/ProtectedRoute';
|
||||
import ProtectedRoute from './components/ProtectedRoute'
|
||||
|
||||
function App() {
|
||||
return (
|
||||
@@ -493,7 +455,7 @@ function App() {
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
</NhostReactProvider>
|
||||
);
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -508,12 +470,12 @@ can use the `useUserData` hook provided by Nhost to do it.
|
||||
So, open the `components/Layout.js` file and use this hook like so:
|
||||
|
||||
```js
|
||||
import { useUserData } from '@nhost/react';
|
||||
import { useUserData } from '@nhost/react'
|
||||
|
||||
const Layout = () => {
|
||||
const user = useUserData();
|
||||
const user = useUserData()
|
||||
//...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
That's it! The JSX code for rendering the user data (email, display name, etc.)
|
||||
@@ -552,14 +514,14 @@ Then, add the `NhostApolloProvider` from `@nhost/react-apollo` into your
|
||||
`App.js` file.
|
||||
|
||||
```jsx title="src/App.js"
|
||||
import { NhostApolloProvider } from '@nhost/react-apollo';
|
||||
import { NhostApolloProvider } from '@nhost/react-apollo'
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<NhostReactProvider nhost={nhost}>
|
||||
<NhostApolloProvider nhost={nhost}>{/* ... */}</NhostApolloProvider>
|
||||
</NhostReactProvider>
|
||||
);
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -567,28 +529,24 @@ From there, we can construct our GraphQL query and use the Apollo `useMutation`
|
||||
hook to execute that query when the user submits the form from the profile page:
|
||||
|
||||
```js title="src/pages/Profile.js"
|
||||
import { gql, useMutation } from '@apollo/client';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import { gql, useMutation } from '@apollo/client'
|
||||
import { toast } from 'react-hot-toast'
|
||||
|
||||
const UPDATE_USER_MUTATION = gql`
|
||||
mutation ($id: uuid!, $displayName: String!, $metadata: jsonb) {
|
||||
updateUser(
|
||||
pk_columns: { id: $id }
|
||||
_set: { displayName: $displayName, metadata: $metadata }
|
||||
) {
|
||||
updateUser(pk_columns: { id: $id }, _set: { displayName: $displayName, metadata: $metadata }) {
|
||||
id
|
||||
displayName
|
||||
metadata
|
||||
}
|
||||
}
|
||||
`;
|
||||
`
|
||||
|
||||
const Profile = () => {
|
||||
const [mutateUser, { loading: updatingProfile }] =
|
||||
useMutation(UPDATE_USER_MUTATION);
|
||||
const [mutateUser, { loading: updatingProfile }] = useMutation(UPDATE_USER_MUTATION)
|
||||
|
||||
const updateUserProfile = async (e) => {
|
||||
e.preventDefault();
|
||||
e.preventDefault()
|
||||
|
||||
try {
|
||||
await mutateUser({
|
||||
@@ -597,18 +555,18 @@ const Profile = () => {
|
||||
displayName: `${firstName} ${lastName}`.trim(),
|
||||
metadata: {
|
||||
firstName,
|
||||
lastName,
|
||||
},
|
||||
},
|
||||
});
|
||||
toast.success('Updated successfully', { id: 'updateProfile' });
|
||||
lastName
|
||||
}
|
||||
}
|
||||
})
|
||||
toast.success('Updated successfully', { id: 'updateProfile' })
|
||||
} catch (error) {
|
||||
toast.error('Unable to update profile', { id: 'updateProfile' });
|
||||
toast.error('Unable to update profile', { id: 'updateProfile' })
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Finally, since Hasura has an **allow nothing by default** policy, and we haven't
|
||||
@@ -638,7 +596,7 @@ Finally, to add caching, synchronizing, and updating server state in your React
|
||||
So, first add the following GraphQL query to retrieve the current user data from the `Layout` component:
|
||||
|
||||
```js title="src/components/Layout.js"
|
||||
import { gql } from '@apollo/client';
|
||||
import { gql } from '@apollo/client'
|
||||
|
||||
const GET_USER_QUERY = gql`
|
||||
query GetUser($id: uuid!) {
|
||||
@@ -650,37 +608,37 @@ const GET_USER_QUERY = gql`
|
||||
avatarUrl
|
||||
}
|
||||
}
|
||||
`;
|
||||
`
|
||||
|
||||
const Layout = () => {
|
||||
//...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Then, replace the `useUserData` hook with the `useUserId` hook to retrieve the current user's ID.
|
||||
|
||||
```js title="src/components/Layout.js"
|
||||
import { useUserId } from '@nhost/react';
|
||||
import { useUserId } from '@nhost/react'
|
||||
|
||||
const Layout = () => {
|
||||
const id = useUserId();
|
||||
const id = useUserId()
|
||||
//...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Finally, we can run our GraphQL query using the `useQuery` hook and the current user's ID.
|
||||
|
||||
```jsx title="src/components/Layout.js"
|
||||
// highlight-next-line
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
import { gql, useQuery } from '@apollo/client'
|
||||
|
||||
const Layout = () => {
|
||||
const id = useUserId();
|
||||
const id = useUserId()
|
||||
// highlight-start
|
||||
const { loading, error, data } = useQuery(GET_USER_QUERY, {
|
||||
variables: { id },
|
||||
});
|
||||
const user = data?.user;
|
||||
variables: { id }
|
||||
})
|
||||
const user = data?.user
|
||||
// highlight-end
|
||||
|
||||
//...
|
||||
@@ -701,8 +659,8 @@ const Layout = () => {
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
You now have a fully functional React application. Congratulations!
|
||||
@@ -711,4 +669,4 @@ You now have a fully functional React application. Congratulations!
|
||||
|
||||
- Did you enjoy Nhost? Give us a star ⭐ on [Github](https://github.com/nhost/nhost). Thank you!
|
||||
- Check out our more in-depth [examples](https://github.com/nhost/nhost/tree/main/examples).
|
||||
- Build your next app with [Nhost](https://app.nhost.io/)!
|
||||
- Build your next app with [Nhost](https://app.nhost.io/)!
|
||||
|
||||
1189
docs/docs/platform/quickstarts/redwoodjs.mdx
Normal file
1189
docs/docs/platform/quickstarts/redwoodjs.mdx
Normal file
File diff suppressed because it is too large
Load Diff
713
docs/docs/platform/quickstarts/vue.mdx
Normal file
713
docs/docs/platform/quickstarts/vue.mdx
Normal file
@@ -0,0 +1,713 @@
|
||||
---
|
||||
title: 'Quickstart: Vue'
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs'
|
||||
import TabItem from '@theme/TabItem'
|
||||
|
||||
# Quickstart: Vue
|
||||
|
||||
## Introduction
|
||||
|
||||
This quickstart guide provides the steps you need to build a simple Vue app
|
||||
powered by Nhost for the backend. It includes:
|
||||
|
||||
- Database: [PostgreSQL](https://www.postgresql.org/)
|
||||
- Instant GraphQL API: [Hasura](https://hasura.io/)
|
||||
- Authentication: [Hasura Auth](https://github.com/nhost/hasura-auth/)
|
||||
- Storage: [Hasura Storage](https://hub.docker.com/r/nhost/hasura-storage)
|
||||
|
||||
By the end of this guide, you'll have a full-stack app that allows users to log
|
||||
in to access a protected dashboard and update their profile information.
|
||||
|
||||
:::tip
|
||||
You can see the result of this quickstart [in our main repository](https://github.com/nhost/nhost/tree/main/examples/vue-quickstart).
|
||||
|
||||
You can also preview it in the browser: [](https://stackblitz.com/github/nhost/nhost/tree/main/examples/vue-quickstart)
|
||||
:::
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before getting started, let's make sure that your development environment is
|
||||
ready.
|
||||
|
||||
You'll need **Node.js** version 14 or later: [install it from here](https://nodejs.org/en/).
|
||||
|
||||
## Project setup
|
||||
|
||||
### Create a new Nhost app
|
||||
|
||||
import CreateApp from '@site/src/components/create-nhost-app.mdx'
|
||||
|
||||
<CreateApp />
|
||||
|
||||
:::info
|
||||
You can also connect your Nhost app to a GitHub repository. When you do this, any updates you push to your code will automatically be deployed. [Learn more](https://docs.nhost.io/platform/github-integration).
|
||||
:::
|
||||
|
||||
## Initialize the app
|
||||
|
||||
### Create a Vue app
|
||||
|
||||
We will use a simple adaptation of [Vitesse Lite](https://github.com/antfu/vitesse-lite), a ready-to-deploy Vite template by Anthony Fu. We can scaffold it with [degit](https://github.com/Rich-Harris/degit).
|
||||
|
||||
Open your terminal, and run the following command:
|
||||
|
||||
```bash
|
||||
npx degit nhost/vue-quickstart my-nhost-app
|
||||
```
|
||||
|
||||
You can now go into your project directory, install dependencies, and start the development server:
|
||||
|
||||
<Tabs groupId="package-manager">
|
||||
<TabItem value="npm" label="npm" default>
|
||||
|
||||
```bash
|
||||
cd my-nhost-app
|
||||
npm install
|
||||
npm dev
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="yarn" label="Yarn">
|
||||
|
||||
```bash
|
||||
cd my-nhost-app
|
||||
yarn
|
||||
yarn dev
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="pnpm" label="pnpm">
|
||||
|
||||
```bash
|
||||
cd my-nhost-app
|
||||
pnpm install
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
If everything is working fine, your Vue development server should be running
|
||||
on port 3000. Open [http://localhost:3000](http://localhost:3000) from your
|
||||
browser to check this out.
|
||||
|
||||
### Configure Nhost with Vue
|
||||
|
||||
To work with Nhost from within our Vue app, we'll use the
|
||||
[Vue SDK](https://github.com/nhost/nhost/tree/main/packages/react) provided
|
||||
by Nhost. It's a wrapper around the
|
||||
[Nhost JavaScript SDK](https://github.com/nhost/nhost/tree/main/packages/nhost-js) which
|
||||
gives us a way to interact with our Nhost backend using Vue composables.
|
||||
|
||||
You can install the Nhost Vue SDK with:
|
||||
|
||||
<Tabs groupId="package-manager">
|
||||
<TabItem value="npm" label="npm" default>
|
||||
|
||||
```bash
|
||||
npm install @nhost/vue graphql
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="yarn" label="Yarn">
|
||||
|
||||
```bash
|
||||
yarn add @nhost/vue graphql
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="pnpm" label="pnpm">
|
||||
|
||||
```bash
|
||||
pnpm add @nhost/vue graphql
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Next, open your `src/main.ts` file as we'll now configure Nhost inside our app.
|
||||
|
||||
The Nhost Vue SDK comes with a `NhostClient` that can be loaded into the Vue application as a plugin.
|
||||
It makes the authentication state and all the provided Vue composables available in our
|
||||
application.
|
||||
|
||||
Use the following code to instantiate a new Nhost client and link it to your
|
||||
Nhost backend:
|
||||
|
||||
```tsx title="src/main.ts"
|
||||
import { createApp } from 'vue'
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import routes from 'virtual:generated-pages'
|
||||
// highlight-start
|
||||
import { NhostClient } from '@nhost/vue'
|
||||
// highlight-end
|
||||
import App from './App.vue'
|
||||
|
||||
import '@unocss/reset/tailwind.css'
|
||||
import './styles/main.css'
|
||||
import 'uno.css'
|
||||
|
||||
// highlight-start
|
||||
const nhost = new NhostClient({
|
||||
backendUrl: import.meta.env.VITE_NHOST_URL
|
||||
})
|
||||
// highlight-end
|
||||
|
||||
const app = createApp(App)
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes
|
||||
})
|
||||
app
|
||||
.use(router)
|
||||
// highlight-start
|
||||
.use(nhost)
|
||||
// highlight-end
|
||||
app.mount('#app')
|
||||
```
|
||||
|
||||
Finally, make sure to create an environment variable named
|
||||
`VITE_NHOST_URL` to store your Nhost backend URL:
|
||||
|
||||
```bash title=".env"
|
||||
VITE_NHOST_URL=YOUR_NHOST_BACKEND_URL
|
||||
```
|
||||
|
||||
You can find your Nhost backend URL for your project from [your dashboard](https://app.nhost.io) as shown below:
|
||||
|
||||

|
||||
|
||||
## Build the app
|
||||
|
||||
### Add authentication
|
||||
|
||||
#### 1. Sign-up
|
||||
|
||||
The next step is to allow our users to authenticate into our application.
|
||||
Let's start with implementing the sign-up process.
|
||||
|
||||
For that, we'll use the `useSignUpEmailPassword` composable provided by the Nhost
|
||||
Vue SDK within a `/sign-up` page.
|
||||
|
||||
Let's create a new page in your project using the following code:
|
||||
|
||||
```markup title="src/pages/sign-up.vue"
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { useSignUpEmailPassword } from '@nhost/vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const { signUpEmailPassword, needsEmailVerification } = useSignUpEmailPassword()
|
||||
const router = useRouter()
|
||||
const firstName = ref('')
|
||||
const lastName = ref('')
|
||||
const email = ref('')
|
||||
const password = ref('')
|
||||
const handleSubmit = async (event: Event) => {
|
||||
event.preventDefault()
|
||||
const { isSuccess } = await signUpEmailPassword(email, password, {
|
||||
metadata: { firstName, lastName }
|
||||
})
|
||||
if (isSuccess) router.push('/')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<p v-if="needsEmailVerification">
|
||||
Please check your mailbox and follow the verification link to verify your email.
|
||||
</p>
|
||||
|
||||
<form v-else @submit="handleSubmit">
|
||||
<input v-model="firstName" placeholder="First name" class="input" /><br />
|
||||
<input v-model="lastName" placeholder="Last name" class="input" /><br />
|
||||
<input v-model="email" type="email" placeholder="Email" class="input" /><br />
|
||||
<input v-model="password" type="password" placeholder="Password" class="input" /><br />
|
||||
|
||||
<button class="btn-submit" type="submit">Sign up</button>
|
||||
</form>
|
||||
</template>
|
||||
```
|
||||
|
||||
#### 2. Sign-in
|
||||
|
||||
Now that new users can sign up for our application, let's see how to allow
|
||||
existing users to sign in with email and password.
|
||||
|
||||
For that, we will use the Nhost composable named `useSignInEmailPassword` inside a new
|
||||
`sign-in` page the same way we did with our `sign-up` page. Let's create a `src/pages/sign-in.vue` component:
|
||||
|
||||
```markup title="src/pages/sign-in.vue"
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { useSignInEmailPassword } from '@nhost/vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
const { signInEmailPassword, needsEmailVerification } = useSignInEmailPassword()
|
||||
const router = useRouter()
|
||||
const email = ref('')
|
||||
const password = ref('')
|
||||
const handleSubmit = async (event: Event) => {
|
||||
event.preventDefault()
|
||||
const { isSuccess } = await signInEmailPassword(email, password)
|
||||
if (isSuccess) router.push('/')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<p v-if="needsEmailVerification">
|
||||
Your email is not yet verified. Please check your mailbox and follow the verification link
|
||||
finish registration.
|
||||
</p>
|
||||
|
||||
<form v-else @submit="handleSubmit">
|
||||
<input v-model="email" type="email" placeholder="Email" class="input" /><br />
|
||||
<input v-model="password" type="password" placeholder="Password" class="input" /><br />
|
||||
|
||||
<button class="btn-submit" type="submit">Sign in</button>
|
||||
<p>No account yet? <router-link to="/sign-up"> Sign up </router-link></p>
|
||||
</form>
|
||||
</template>
|
||||
```
|
||||
|
||||
#### 3. Home page
|
||||
|
||||
Let's also add links to sign up and sign in in our index page.
|
||||
|
||||
```markup title="src/pages/index.vue"
|
||||
<template>
|
||||
<div>
|
||||
<div i-carbon-home text-4xl inline-block />
|
||||
<p>Nhost with Vue</p>
|
||||
<p>
|
||||
<em text-sm op75>Quickstart</em>
|
||||
</p>
|
||||
<div py-4 />
|
||||
<router-link class="btn" to="/sign-up"> Sign Up </router-link><br />
|
||||
<router-link class="btn" to="/sign-in"> Sign In </router-link>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
#### 4. Sign-out
|
||||
|
||||
Finally, to allow the users to sign out from the app, we can use the Nhost
|
||||
`useSignOut` composable. We'll also use `useAuthenticationStatus` to show the button only when the user is authenticated:
|
||||
|
||||
```markup title="src/components/Footer.vue"
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useAuthenticated, useSignOut } from '@nhost/vue'
|
||||
import { isDark, toggleDark } from '~/composables'
|
||||
const isAuthenticated = useAuthenticated()
|
||||
const { signOut } = useSignOut()
|
||||
const router = useRouter()
|
||||
const handleSignOut = () => {
|
||||
signOut()
|
||||
router.push('/')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<nav text-xl mt-6 inline-flex gap-2>
|
||||
<button class="icon-btn !outline-none" @click="toggleDark()">
|
||||
<div v-if="isDark" i-carbon-moon />
|
||||
<div v-else i-carbon-sun />
|
||||
</button>
|
||||
|
||||
<button v-if="isAuthenticated" class="icon-btn !outline-none" @click="handleSignOut">
|
||||
<div i-carbon-logout />
|
||||
</button>
|
||||
</nav>
|
||||
</template>
|
||||
```
|
||||
|
||||
### Protect routes
|
||||
|
||||
Now that we have implemented authentication, we can easily decide who can access
|
||||
certain parts of our application.
|
||||
|
||||
Let's create a profile page that will be only accessible to authenticated users. If an unauthenticated user attempts to load it, it will redirect them to the `/sign-up` page:
|
||||
|
||||
```markup title="src/pages/profile.vue"
|
||||
<template>
|
||||
<div>
|
||||
<div i-carbon-home text-4xl inline-block />
|
||||
<p>Profile page</p>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
Then, we can use a [beforeEach navigation guqes](https://router.vuejs.org/guide/advanced/navigation-guards.html#global-before-guards) in our `main.ts` file:
|
||||
|
||||
```tsx title="src/main.ts"
|
||||
import { createApp } from 'vue'
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import routes from 'virtual:generated-pages'
|
||||
import { NhostClient } from '@nhost/vue'
|
||||
import App from './App.vue'
|
||||
|
||||
import '@unocss/reset/tailwind.css'
|
||||
import './styles/main.css'
|
||||
import 'uno.css'
|
||||
|
||||
const nhost = new NhostClient({
|
||||
backendUrl: import.meta.env.VITE_NHOST_URL
|
||||
})
|
||||
|
||||
const app = createApp(App)
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes
|
||||
})
|
||||
|
||||
// highlight-start
|
||||
router.beforeEach(async (to) => {
|
||||
if (to.path === '/profile' && !(await nhost.auth.isAuthenticatedAsync())) {
|
||||
return '/sign-in'
|
||||
}
|
||||
return true
|
||||
})
|
||||
// highlight-end
|
||||
|
||||
app.use(router).use(nhost)
|
||||
app.mount('#app')
|
||||
```
|
||||
|
||||
Let's finally add a link to the profile page in the index page `/`:
|
||||
|
||||
```markup title="src/pages/index.vue"
|
||||
<template>
|
||||
<div>
|
||||
<div i-carbon-home text-4xl inline-block />
|
||||
<p>Nhost with Vue</p>
|
||||
<p>
|
||||
<em text-sm op75>Quickstart</em>
|
||||
</p>
|
||||
<div py-4 />
|
||||
<!-- highlight-start -->
|
||||
<router-link class="btn" to="/profile"> Profile </router-link><br />
|
||||
<!-- highlight-end -->
|
||||
<router-link class="btn" to="/sign-up"> Sign Up </router-link><br />
|
||||
<router-link class="btn" to="/sign-in"> Sign In </router-link>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
### Retrieve user data
|
||||
|
||||
Finally, let's display the information of the authenticated user throughout his
|
||||
dashboard to make the app more personalized.
|
||||
|
||||
Getting the current authenticated user data is quite easy. Indeed, we
|
||||
can use the `useUserData` composable provided by Nhost to do it. When the user is authenticated, it returns the information fetched from the `users` table, such as the display name, the email, or the user's roles. This composable returns `null` until the user is effectively authenticated.
|
||||
|
||||
Let's update the profile page to use it:
|
||||
|
||||
```markup title="src/pages/profile.vue"
|
||||
<!-- highlight-start -->
|
||||
<script setup lang="ts">
|
||||
import { useUserData } from '@nhost/vue'
|
||||
const user = useUserData()
|
||||
</script>
|
||||
<!-- highlight-end -->
|
||||
<template>
|
||||
<div>
|
||||
<div i-carbon-home text-4xl inline-block />
|
||||
<p>Profile page</p>
|
||||
<p>
|
||||
<em text-sm op75>Quickstart</em>
|
||||
</p>
|
||||
<!-- highlight-start -->
|
||||
<div v-if="user" py-4>
|
||||
<p>Hello, {{ user?.displayName }}. Your email is {{ user?.email }}.</p>
|
||||
<!-- highlight-end -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
### Update user data
|
||||
|
||||
Nhost provides a GraphQL API through Hasura so that we can query and mutate our
|
||||
data instantly.
|
||||
|
||||
In this tutorial, we'll use [Vue Apollo v4](https://v4.apollo.vuejs.org) for interacting with
|
||||
this GraphQL API. Nhost comes with a custom Apollo client that syncs the Apollo client with the authentication status of your users.
|
||||
|
||||
So, start by installing the following dependencies:
|
||||
|
||||
<Tabs groupId="package-manager">
|
||||
<TabItem value="npm" label="npm" default>
|
||||
|
||||
```bash
|
||||
npm install @nhost/apollo @apollo/client graphql graphql-tag @vue/apollo-composable
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="yarn" label="Yarn">
|
||||
|
||||
```bash
|
||||
yarn add @nhost/apollo @apollo/client graphql graphql-tag @vue/apollo-composable
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="pnpm" label="pnpm">
|
||||
|
||||
```bash
|
||||
pnpm add @nhost/apollo @apollo/client graphql graphql-tag @vue/apollo-composable
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Then, create the Apollo client in your `src/main.ts` file, and provide it to your Vue app:
|
||||
|
||||
```tsx title="src/main.ts"
|
||||
import { createApp } from 'vue'
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import routes from 'virtual:generated-pages'
|
||||
import { NhostClient } from '@nhost/vue'
|
||||
// highlight-start
|
||||
import { createApolloClient } from '@nhost/apollo'
|
||||
import { DefaultApolloClient } from '@vue/apollo-composable'
|
||||
// highlight-end
|
||||
import App from './App.vue'
|
||||
|
||||
import '@unocss/reset/tailwind.css'
|
||||
import './styles/main.css'
|
||||
import 'uno.css'
|
||||
|
||||
const nhost = new NhostClient({
|
||||
backendUrl: import.meta.env.VITE_NHOST_URL
|
||||
})
|
||||
|
||||
const app = createApp(App)
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes
|
||||
})
|
||||
|
||||
router.beforeEach(async (to) => {
|
||||
if (to.path === '/profile' && !(await nhost.auth.isAuthenticatedAsync())) {
|
||||
return '/sign-in'
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
// highlight-start
|
||||
const apolloClient = createApolloClient({ nhost })
|
||||
// highlight-end
|
||||
|
||||
app
|
||||
.use(router)
|
||||
.use(nhost)
|
||||
// highlight-start
|
||||
.provide(DefaultApolloClient, apolloClient)
|
||||
// highlight-end
|
||||
.mount('#app')
|
||||
```
|
||||
|
||||
From there, we can construct our GraphQL query and use the Apollo `useMutation`
|
||||
composable to execute that query when the user submits the form from the profile page:
|
||||
|
||||
```markup title="src/pages/profile.vue"
|
||||
<script setup lang="ts">
|
||||
import { gql } from '@apollo/client/core'
|
||||
import { useNhostClient, useUserData } from '@nhost/vue'
|
||||
import { useMutation } from '@vue/apollo-composable'
|
||||
import { ref } from 'vue'
|
||||
const user = useUserData()
|
||||
const { nhost } = useNhostClient()
|
||||
const UPDATE_USER_MUTATION = gql`
|
||||
mutation ($id: uuid!, $displayName: String!, $metadata: jsonb) {
|
||||
updateUser(
|
||||
pk_columns: { id: $id }
|
||||
_set: { displayName: $displayName, metadata: $metadata }
|
||||
) {
|
||||
id
|
||||
displayName
|
||||
metadata
|
||||
}
|
||||
}
|
||||
`
|
||||
const firstName = ref('')
|
||||
const lastName = ref('')
|
||||
const { mutate, loading, error } = useMutation(UPDATE_USER_MUTATION)
|
||||
|
||||
const updateUserProfile = async (event: Event) => {
|
||||
event.preventDefault()
|
||||
if (user.value) {
|
||||
await mutate({
|
||||
id: user.value.id,
|
||||
displayName: `${firstName.value} ${lastName.value}`.trim(),
|
||||
metadata: {
|
||||
firstName: firstName.value,
|
||||
lastName: lastName.value
|
||||
}
|
||||
})
|
||||
await client.auth.refreshSession()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div i-carbon-home text-4xl inline-block />
|
||||
<p>Profile page</p>
|
||||
<p>
|
||||
<em text-sm op75>Quickstart</em>
|
||||
</p>
|
||||
<div v-if="user" py-4>
|
||||
<p>Hello, {{ user?.displayName }}. Your email is {{ user?.email }}.</p>
|
||||
<form @submit="updateUserProfile">
|
||||
<input v-model="firstName" placeholder="First name" class="input" /><br />
|
||||
<input v-model="lastName" placeholder="Last name" class="input" /><br />
|
||||
<button className="m-3 text-sm btn" :disabled="loading">Save</button>
|
||||
<div v-if="error">{{ error.message }}</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
:::tip
|
||||
You probably have noticed that we are calling `client.auth.refreshSession()` after we updated the user using the GraphQL mutation. The Nhost client only extracts user information from the access token (JWT), that is kept in memory and refreshed every 15 minutes. As user information has been updated, we force an access token refresh so it is kept up to date.
|
||||
:::
|
||||
|
||||
Finally, since Hasura has an **allow nothing by default** policy, and we haven't
|
||||
set any permissions yet, our GraphQL mutations would fail.
|
||||
|
||||
So, open the Hasura console from the **Data** tab of your project from [your Nhost dashboard](https://app.nhost.io/). Then, go to the **permissions** tab of the `users` table, type in `user` in the role cell, and click the edit icon on the `select` operation:
|
||||
|
||||

|
||||
|
||||
To restrict the user to read his own data only, specify a condition with the user's ID and the `X-Hasura-User-ID` session variable, which is passed with each requests.
|
||||
|
||||

|
||||
|
||||
Next, select the columns you'd like the users to have access to, and click
|
||||
**Save Permissions**.
|
||||
|
||||

|
||||
|
||||
Repeat the same steps on the `update` operation for the `user` role to allow
|
||||
users to update their `displayName` and `metadata` only.
|
||||
|
||||
Finally, to add real-time caching, synchronizing, and updating server state in your Vue app, let's refactor the user data fetching using the Apollo client and our GraphQL API instead.
|
||||
|
||||
First add the following GraphQL subscription to retrieve the current user data component:
|
||||
|
||||
```ts title="src/pages/profile.vue"
|
||||
import { gql } from '@apollo/client/core'
|
||||
|
||||
const GET_USER_SUBSCRIPTION = gql`
|
||||
subscription GetUser($id: uuid!) {
|
||||
user(id: $id) {
|
||||
id
|
||||
email
|
||||
displayName
|
||||
metadata
|
||||
avatarUrl
|
||||
}
|
||||
}
|
||||
`
|
||||
```
|
||||
|
||||
Then, replace the `useUserData` composable with the `useUserId` composable to retrieve the current user's ID.
|
||||
|
||||
```ts title="src/pages/profile.vue"
|
||||
import { useUserId } from '@nhost/vue'
|
||||
|
||||
const id = useUserId()
|
||||
```
|
||||
|
||||
Finally, we can run our GraphQL subscription using the `useSubscription` composable and the current user's ID. Here is the full `profile.vue` page:
|
||||
|
||||
```markup title="src/pages/profile.vue"
|
||||
<script setup lang="ts">
|
||||
import { gql } from '@apollo/client/core'
|
||||
import { useNhostClient, useUserId } from '@nhost/vue'
|
||||
import { useMutation, useSubscription } from '@vue/apollo-composable'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
const { nhost } = useNhostClient()
|
||||
const GET_USER_SUBSCRIPTION = gql`
|
||||
subscription GetUser($id: uuid!) {
|
||||
user(id: $id) {
|
||||
id
|
||||
email
|
||||
displayName
|
||||
metadata
|
||||
avatarUrl
|
||||
}
|
||||
}
|
||||
`
|
||||
const id = useUserId()
|
||||
|
||||
const { result } = useSubscription(
|
||||
GET_USER_SUBSCRIPTION,
|
||||
computed(() => ({ id: id.value }))
|
||||
)
|
||||
const user = computed(() => result.value?.user)
|
||||
|
||||
const UPDATE_USER_MUTATION = gql`
|
||||
mutation ($id: uuid!, $displayName: String!, $metadata: jsonb) {
|
||||
updateUser(
|
||||
pk_columns: { id: $id }
|
||||
_set: { displayName: $displayName, metadata: $metadata }
|
||||
) {
|
||||
id
|
||||
displayName
|
||||
metadata
|
||||
}
|
||||
}
|
||||
`
|
||||
const firstName = ref('')
|
||||
const lastName = ref('')
|
||||
const { mutate, loading, error } = useMutation(UPDATE_USER_MUTATION)
|
||||
|
||||
const updateUserProfile = async (event: Event) => {
|
||||
event.preventDefault()
|
||||
if (user.value) {
|
||||
await mutate({
|
||||
id: user.value.id,
|
||||
displayName: `${firstName.value} ${lastName.value}`.trim(),
|
||||
metadata: {
|
||||
firstName: firstName.value,
|
||||
lastName: lastName.value
|
||||
}
|
||||
})
|
||||
await nhost.auth.refreshSession()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div i-carbon-home text-4xl inline-block />
|
||||
<p>Profile page</p>
|
||||
<p>
|
||||
<em text-sm op75>Quickstart</em>
|
||||
</p>
|
||||
<div v-if="user" py-4>
|
||||
<p>Hello, {{ user.displayName }}. Your email is {{ user.email }}.</p>
|
||||
<form @submit="updateUserProfile">
|
||||
<input v-model="firstName" placeholder="First name" class="input" /><br />
|
||||
<input v-model="lastName" placeholder="Last name" class="input" /><br />
|
||||
<button className="m-3 text-sm btn" :disabled="loading">Save</button>
|
||||
<div v-if="error">{{ error.message }}</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
You now have a fully functional Vue application. Congratulations!
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Did you enjoy Nhost? Give us a star ⭐ on [Github](https://github.com/nhost/nhost). Thank you!
|
||||
- Check out our more in-depth [examples](https://github.com/nhost/nhost/tree/main/examples).
|
||||
- Build your next app with [Nhost](https://app.nhost.io/)!
|
||||
@@ -4,7 +4,7 @@ title: signUp()
|
||||
sidebar_label: signUp()
|
||||
slug: /reference/javascript/auth/sign-up
|
||||
description: Use `nhost.auth.signUp` to sign up a user using email and password. If you want to sign up a user using passwordless email (Magic Link), SMS, or an OAuth provider, use the `signIn` function instead.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L93
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L101
|
||||
---
|
||||
|
||||
# `signUp()`
|
||||
@@ -22,12 +22,12 @@ nhost.auth.signUp({
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> [`SignUpEmailPasswordParams`](/reference/docgen/javascript/auth/types/sign-up-email-password-params)
|
||||
**<span className="parameter-name">\_\_namedParameters</span>** <span className="optional-status">required</span> [`SignUpEmailPasswordParams`](/reference/docgen/javascript/auth/types/sign-up-email-password-params)
|
||||
|
||||
| Property | Type | Required | Notes |
|
||||
| :------------------------------------------------------------------------------------------ | :-------------- | :------: | :---- |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>password</span> | `string` | ✔️ | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>email</span> | `string` | ✔️ | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>options</span> | `SignUpOptions` | | |
|
||||
| Property | Type | Required | Notes |
|
||||
| :------------------------------------------------------------------------------------------------------- | :-------------- | :------: | :---- |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>password</span> | `string` | ✔️ | |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>email</span> | `string` | ✔️ | |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>options</span> | `SignUpOptions` | | |
|
||||
|
||||
---
|
||||
|
||||
@@ -4,7 +4,7 @@ title: signIn()
|
||||
sidebar_label: signIn()
|
||||
slug: /reference/javascript/auth/sign-in
|
||||
description: Use `nhost.auth.signIn` to sign in a user using email and password, passwordless (email or sms) or an external provider. `signIn` can be used to sign in a user in various ways depending on the parameters.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L156
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L144
|
||||
---
|
||||
|
||||
# `signIn()`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: signOut()
|
||||
sidebar_label: signOut()
|
||||
slug: /reference/javascript/auth/sign-out
|
||||
description: Use `nhost.auth.signOut` to sign out the user.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L338
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L256
|
||||
---
|
||||
|
||||
# `signOut()`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: resetPassword()
|
||||
sidebar_label: resetPassword()
|
||||
slug: /reference/javascript/auth/reset-password
|
||||
description: Use `nhost.auth.resetPassword` to reset the password for a user. This will send a reset-password link in an email to the user. When the user clicks the reset-password link the user is automatically signed-in. Once signed-in, the user can change their password using `nhost.auth.changePassword()`.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L365
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L272
|
||||
---
|
||||
|
||||
# `resetPassword()`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: changePassword()
|
||||
sidebar_label: changePassword()
|
||||
slug: /reference/javascript/auth/change-password
|
||||
description: Use `nhost.auth.changePassword` to change the password for the user. The old password is not needed.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L390
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L288
|
||||
---
|
||||
|
||||
# `changePassword()`
|
||||
@@ -19,10 +19,10 @@ nhost.auth.changePassword({ newPassword: 'new-secret-password' })
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> [`ChangePasswordParams`](/reference/docgen/javascript/auth/types/change-password-params)
|
||||
**<span className="parameter-name">\_\_namedParameters</span>** <span className="optional-status">required</span> [`ChangePasswordParams`](/reference/docgen/javascript/auth/types/change-password-params)
|
||||
|
||||
| Property | Type | Required | Notes |
|
||||
| :--------------------------------------------------------------------------------------------- | :------- | :------: | :---- |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>newPassword</span> | `string` | ✔️ | |
|
||||
| Property | Type | Required | Notes |
|
||||
| :---------------------------------------------------------------------------------------------------------- | :------- | :------: | :---- |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>newPassword</span> | `string` | ✔️ | |
|
||||
|
||||
---
|
||||
|
||||
@@ -4,7 +4,7 @@ title: sendVerificationEmail()
|
||||
sidebar_label: sendVerificationEmail()
|
||||
slug: /reference/javascript/auth/send-verification-email
|
||||
description: Use `nhost.auth.sendVerificationEmail` to send a verification email to the specified email. The email contains a verification-email link. When the user clicks the verification-email link their email is verified.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L415
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L304
|
||||
---
|
||||
|
||||
# `sendVerificationEmail()`
|
||||
@@ -19,11 +19,11 @@ nhost.auth.sendVerificationEmail({ email: 'joe@example.com' })
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> [`SendVerificationEmailParams`](/reference/docgen/javascript/auth/types/send-verification-email-params)
|
||||
**<span className="parameter-name">\_\_namedParameters</span>** <span className="optional-status">required</span> [`SendVerificationEmailParams`](/reference/docgen/javascript/auth/types/send-verification-email-params)
|
||||
|
||||
| Property | Type | Required | Notes |
|
||||
| :----------------------------------------------------------------------------------------- | :--------------- | :------: | :---- |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>email</span> | `string` | ✔️ | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>options</span> | `RedirectOption` | | |
|
||||
| Property | Type | Required | Notes |
|
||||
| :------------------------------------------------------------------------------------------------------ | :--------------- | :------: | :---- |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>email</span> | `string` | ✔️ | |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>options</span> | `RedirectOption` | | |
|
||||
|
||||
---
|
||||
|
||||
@@ -4,7 +4,7 @@ title: changeEmail()
|
||||
sidebar_label: changeEmail()
|
||||
slug: /reference/javascript/auth/change-email
|
||||
description: Use `nhost.auth.changeEmail` to change a user's email. This will send a confirm-email-change link in an email to the new email. Once the user clicks on the confirm-email-change link the email will be change to the new email.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L442
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L323
|
||||
---
|
||||
|
||||
# `changeEmail()`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: deanonymize()
|
||||
sidebar_label: deanonymize()
|
||||
slug: /reference/javascript/auth/deanonymize
|
||||
description: Use `nhost.auth.deanonymize` to deanonymize a user.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L467
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L339
|
||||
---
|
||||
|
||||
# `deanonymize()`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: onTokenChanged()
|
||||
sidebar_label: onTokenChanged()
|
||||
slug: /reference/javascript/auth/on-token-changed
|
||||
description: Use `nhost.auth.onTokenChanged` to add a custom function that runs every time the access or refresh token is changed.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L501
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L373
|
||||
---
|
||||
|
||||
# `onTokenChanged()`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: onAuthStateChanged()
|
||||
sidebar_label: onAuthStateChanged()
|
||||
slug: /reference/javascript/auth/on-auth-state-changed
|
||||
description: Use `nhost.auth.onAuthStateChanged` to add a custom function that runs every time the authentication status of the user changes. E.g. add a custom function that runs every time the authentication status changes from signed-in to signed-out.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L536
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L408
|
||||
---
|
||||
|
||||
# `onAuthStateChanged()`
|
||||
|
||||
@@ -4,13 +4,20 @@ title: isAuthenticated()
|
||||
sidebar_label: isAuthenticated()
|
||||
slug: /reference/javascript/auth/is-authenticated
|
||||
description: Use `nhost.auth.isAuthenticated` to check if the user is authenticated or not.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L578
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L450
|
||||
---
|
||||
|
||||
# `isAuthenticated()`
|
||||
|
||||
Use `nhost.auth.isAuthenticated` to check if the user is authenticated or not.
|
||||
|
||||
Note: `nhost.auth.isAuthenticated()` can return `false` for two reasons:
|
||||
|
||||
1. The user is not authenticated
|
||||
2. The user is not authenticated but _might_ be authenticated soon (loading) because there is a network request in transit.
|
||||
|
||||
Use `nhost.auth.getAuthenticationStatus` to get both authentication and loading status.
|
||||
|
||||
```ts
|
||||
const isAuthenticated = nhost.auth.isAuthenticated()
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ title: isAuthenticatedAsync()
|
||||
sidebar_label: isAuthenticatedAsync()
|
||||
slug: /reference/javascript/auth/is-authenticated-async
|
||||
description: Use `nhost.auth.isAuthenticatedAsync` to wait (await) for any internal authentication network requests to finish and then return the authentication status.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L596
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L468
|
||||
---
|
||||
|
||||
# `isAuthenticatedAsync()`
|
||||
|
||||
@@ -4,13 +4,16 @@ title: getAuthenticationStatus()
|
||||
sidebar_label: getAuthenticationStatus()
|
||||
slug: /reference/javascript/auth/get-authentication-status
|
||||
description: Use `nhost.auth.getAuthenticationStatus` to get the authentication status of the user.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L621
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L494
|
||||
---
|
||||
|
||||
# `getAuthenticationStatus()`
|
||||
|
||||
Use `nhost.auth.getAuthenticationStatus` to get the authentication status of the user.
|
||||
|
||||
If `isLoading` is `true`, the client doesn't know whether the user is authenticated yet or not
|
||||
because some internal authentication network requests have not been resolved yet.
|
||||
|
||||
```ts
|
||||
const { isAuthenticated, isLoading } = nhost.auth.getAuthenticationStatus()
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ title: getAccessToken()
|
||||
sidebar_label: getAccessToken()
|
||||
slug: /reference/javascript/auth/get-access-token
|
||||
description: Use `nhost.auth.getAccessToken` to get the access token of the user.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L649
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L524
|
||||
---
|
||||
|
||||
# `getAccessToken()`
|
||||
@@ -1,15 +0,0 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: getJWTToken()
|
||||
sidebar_label: getJWTToken()
|
||||
slug: /reference/javascript/auth/get-jwt-token
|
||||
sidebar_class_name: deprecated
|
||||
description: No description provided.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L635
|
||||
---
|
||||
|
||||
# `getJWTToken()`
|
||||
|
||||
:::caution Deprecated
|
||||
Use `nhost.auth.getAccessToken()` instead.
|
||||
:::
|
||||
@@ -4,13 +4,17 @@ title: getDecodedAccessToken()
|
||||
sidebar_label: getDecodedAccessToken()
|
||||
slug: /reference/javascript/auth/get-decoded-access-token
|
||||
description: Use `nhost.auth.getDecodedAccessToken` to get the decoded access token of the user.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L663
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L539
|
||||
---
|
||||
|
||||
# `getDecodedAccessToken()`
|
||||
|
||||
Use `nhost.auth.getDecodedAccessToken` to get the decoded access token of the user.
|
||||
|
||||
**`@see`**
|
||||
|
||||
{@link https://hasura.io/docs/latest/graphql/core/auth/authentication/jwt/| Hasura documentation}
|
||||
|
||||
```ts
|
||||
const decodedAccessToken = nhost.auth.getDecodedAccessToken()
|
||||
```
|
||||
@@ -4,13 +4,17 @@ title: getHasuraClaims()
|
||||
sidebar_label: getHasuraClaims()
|
||||
slug: /reference/javascript/auth/get-hasura-claims
|
||||
description: Use `nhost.auth.getHasuraClaims` to get the Hasura claims of the user.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L679
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L556
|
||||
---
|
||||
|
||||
# `getHasuraClaims()`
|
||||
|
||||
Use `nhost.auth.getHasuraClaims` to get the Hasura claims of the user.
|
||||
|
||||
**`@see`**
|
||||
|
||||
{@link https://hasura.io/docs/latest/graphql/core/auth/authentication/jwt/| Hasura documentation}
|
||||
|
||||
```ts
|
||||
const hasuraClaims = nhost.auth.getHasuraClaims()
|
||||
```
|
||||
@@ -4,13 +4,17 @@ title: getHasuraClaim()
|
||||
sidebar_label: getHasuraClaim()
|
||||
slug: /reference/javascript/auth/get-hasura-claim
|
||||
description: Use `nhost.auth.getHasuraClaim` to get the value of a specific Hasura claim of the user.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L696
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L574
|
||||
---
|
||||
|
||||
# `getHasuraClaim()`
|
||||
|
||||
Use `nhost.auth.getHasuraClaim` to get the value of a specific Hasura claim of the user.
|
||||
|
||||
**`@see`**
|
||||
|
||||
{@link https://hasura.io/docs/latest/graphql/core/auth/authentication/jwt/| Hasura documentation}
|
||||
|
||||
```ts
|
||||
// if `x-hasura-company-id` exists as a custom claim
|
||||
const companyId = nhost.auth.getHsauraClaim('company-id')
|
||||
@@ -4,13 +4,15 @@ title: refreshSession()
|
||||
sidebar_label: refreshSession()
|
||||
slug: /reference/javascript/auth/refresh-session
|
||||
description: Use `nhost.auth.refreshSession` to refresh the session with either the current internal refresh token or an external refresh token.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L719
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L597
|
||||
---
|
||||
|
||||
# `refreshSession()`
|
||||
|
||||
Use `nhost.auth.refreshSession` to refresh the session with either the current internal refresh token or an external refresh token.
|
||||
|
||||
Note: The Nhost client automatically refreshes the session when the user is authenticated but `nhost.auth.refreshSession` can be useful in some special cases.
|
||||
|
||||
```ts
|
||||
// Refresh the session with the the current internal refresh token.
|
||||
nhost.auth.refreshToken()
|
||||
@@ -4,7 +4,7 @@ title: getSession()
|
||||
sidebar_label: getSession()
|
||||
slug: /reference/javascript/auth/get-session
|
||||
description: Use `nhost.auth.getSession()` to get the session of the user.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L763
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L641
|
||||
---
|
||||
|
||||
# `getSession()`
|
||||
@@ -4,7 +4,7 @@ title: getUser()
|
||||
sidebar_label: getUser()
|
||||
slug: /reference/javascript/auth/get-user
|
||||
description: Use `nhost.auth.getUser()` to get the signed-in user.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L778
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L656
|
||||
---
|
||||
|
||||
# `getUser()`
|
||||
@@ -12,5 +12,5 @@ custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-j
|
||||
Use `nhost.auth.getUser()` to get the signed-in user.
|
||||
|
||||
```ts
|
||||
const user = nhsot.auth.getUser()
|
||||
const user = nhost.auth.getUser()
|
||||
```
|
||||
@@ -4,7 +4,7 @@ title: HasuraAuthClient
|
||||
sidebar_label: Auth
|
||||
description: No description provided.
|
||||
slug: /reference/javascript/auth
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L51
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L59
|
||||
---
|
||||
|
||||
# `HasuraAuthClient`
|
||||
@@ -15,17 +15,15 @@ custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-j
|
||||
|
||||
**<span className="parameter-name">\_\_namedParameters</span>** <span className="optional-status">required</span> [`NhostAuthConstructorParams`](/reference/docgen/javascript/auth/types/nhost-auth-constructor-params)
|
||||
|
||||
| Property | Type | Required | Notes |
|
||||
| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------ | :------: | :---------------------------------------------------------------------------------------------------------------- |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>url</span> | `string` | ✔️ | |
|
||||
| <span className="parameter-name deprecated"><span className="light-grey">\_\_namedParameters.</span>autoLogin</span> <span className="deprecation-sign" title="@alias autoSignIn - use autoSignIn instead">⚠️</span> | `boolean` | | |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>start</span> | `boolean` | | |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>autoSignIn</span> | `boolean` | | When set to true, will parse the url on startup to check if it contains a refresh token to start the session with |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>autoRefreshToken</span> | `boolean` | | When set to true, will automatically refresh token before it expires |
|
||||
| <span className="parameter-name deprecated"><span className="light-grey">\_\_namedParameters.</span>clientStorageSetter</span> <span className="deprecation-sign" title="Use clientStorage / clientStorageType instead">⚠️</span> | [`StorageSetter`](/reference/docgen/javascript/auth/types/storage-setter) | | Define a way to set information about the refresh token and its exipration date. |
|
||||
| <span className="parameter-name deprecated"><span className="light-grey">\_\_namedParameters.</span>clientStorageGetter</span> <span className="deprecation-sign" title="Use clientStorage / clientStorageType instead">⚠️</span> | [`StorageGetter`](/reference/docgen/javascript/auth/types/storage-getter) | | |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>clientStorage</span> | `ClientStorage` | | Object where the refresh token will be persisted and read locally. |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>clientStorageType</span> | `ClientStorageType` | | Define a way to get information about the refresh token and its exipration date. |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>refreshIntervalTime</span> | `number` | | Time interval until token refreshes, in seconds |
|
||||
| Property | Type | Required | Notes |
|
||||
| :------------------------------------------------------------------------------------------------------------------ | :------------------ | :------: | :---------------------------------------------------------------------------------------------------------------- |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>url</span> | `string` | ✔️ | |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>start</span> | `boolean` | | |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>devTools</span> | `boolean` | | Activate devTools e.g. the ability to connect to the xstate inspector |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>autoSignIn</span> | `boolean` | | When set to true, will parse the url on startup to check if it contains a refresh token to start the session with |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>autoRefreshToken</span> | `boolean` | | When set to true, will automatically refresh token before it expires |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>clientStorage</span> | `ClientStorage` | | Object where the refresh token will be persisted and read locally. |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>clientStorageType</span> | `ClientStorageType` | | Define a way to get information about the refresh token and its exipration date. |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>refreshIntervalTime</span> | `number` | | Time interval until token refreshes, in seconds |
|
||||
|
||||
---
|
||||
|
||||
@@ -4,7 +4,7 @@ title: ApiChangeEmailResponse
|
||||
sidebar_label: ApiChangeEmailResponse
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L166
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L178
|
||||
---
|
||||
|
||||
# `ApiChangeEmailResponse`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: ApiChangePasswordResponse
|
||||
sidebar_label: ApiChangePasswordResponse
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L158
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L170
|
||||
---
|
||||
|
||||
# `ApiChangePasswordResponse`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: ApiDeanonymizeResponse
|
||||
sidebar_label: ApiDeanonymizeResponse
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L170
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L182
|
||||
---
|
||||
|
||||
# `ApiDeanonymizeResponse`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: ApiRefreshTokenResponse
|
||||
sidebar_label: ApiRefreshTokenResponse
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L146
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L158
|
||||
---
|
||||
|
||||
# `ApiRefreshTokenResponse`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: ApiResetPasswordResponse
|
||||
sidebar_label: ApiResetPasswordResponse
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L154
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L166
|
||||
---
|
||||
|
||||
# `ApiResetPasswordResponse`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: ApiSendVerificationEmailResponse
|
||||
sidebar_label: ApiSendVerificationEmailResponse
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L162
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L174
|
||||
---
|
||||
|
||||
# `ApiSendVerificationEmailResponse`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: ApiSignInData
|
||||
sidebar_label: ApiSignInData
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L135
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L147
|
||||
---
|
||||
|
||||
# `ApiSignInData`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: ApiSignInResponse
|
||||
sidebar_label: ApiSignInResponse
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L139
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L151
|
||||
---
|
||||
|
||||
# `ApiSignInResponse`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: ApiSignOutResponse
|
||||
sidebar_label: ApiSignOutResponse
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L150
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L162
|
||||
---
|
||||
|
||||
# `ApiSignOutResponse`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: ApiSignUpEmailPasswordResponse
|
||||
sidebar_label: ApiSignUpEmailPasswordResponse
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L131
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L143
|
||||
---
|
||||
|
||||
# `ApiSignUpEmailPasswordResponse`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: AuthChangeEvent
|
||||
sidebar_label: AuthChangeEvent
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L113
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L125
|
||||
---
|
||||
|
||||
# `AuthChangeEvent`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: AuthChangedFunction
|
||||
sidebar_label: AuthChangedFunction
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L115
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L127
|
||||
---
|
||||
|
||||
# `AuthChangedFunction`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: ChangeEmailParams
|
||||
sidebar_label: ChangeEmailParams
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L87
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L99
|
||||
---
|
||||
|
||||
# `ChangeEmailParams`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: ChangePasswordParams
|
||||
sidebar_label: ChangePasswordParams
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L78
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L90
|
||||
---
|
||||
|
||||
# `ChangePasswordParams`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: DeanonymizeParams
|
||||
sidebar_label: DeanonymizeParams
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L93
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L105
|
||||
---
|
||||
|
||||
# `DeanonymizeParams`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: Headers
|
||||
sidebar_label: Headers
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L124
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L136
|
||||
---
|
||||
|
||||
# `Headers`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: LoginData
|
||||
sidebar_label: LoginData
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L119
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L131
|
||||
---
|
||||
|
||||
# `LoginData`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: Mfa
|
||||
sidebar_label: Mfa
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L127
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L139
|
||||
---
|
||||
|
||||
# `Mfa`
|
||||
|
||||
@@ -17,15 +17,13 @@ custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-j
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name deprecated">autoLogin</span>** <span className="optional-status">optional</span> `boolean`
|
||||
|
||||
:::caution Deprecated
|
||||
@alias autoSignIn - use autoSignIn instead
|
||||
:::
|
||||
**<span className="parameter-name">start</span>** <span className="optional-status">optional</span> `boolean`
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">start</span>** <span className="optional-status">optional</span> `boolean`
|
||||
**<span className="parameter-name">devTools</span>** <span className="optional-status">optional</span> `boolean`
|
||||
|
||||
Activate devTools e.g. the ability to connect to the xstate inspector
|
||||
|
||||
---
|
||||
|
||||
@@ -41,28 +39,22 @@ When set to true, will automatically refresh token before it expires
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name deprecated">clientStorageSetter</span>** <span className="optional-status">optional</span> [`StorageSetter`](/reference/docgen/javascript/auth/types/storage-setter)
|
||||
|
||||
Define a way to set information about the refresh token and its exipration date.
|
||||
|
||||
:::caution Deprecated
|
||||
Use clientStorage / clientStorageType instead
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name deprecated">clientStorageGetter</span>** <span className="optional-status">optional</span> [`StorageGetter`](/reference/docgen/javascript/auth/types/storage-getter)
|
||||
|
||||
:::caution Deprecated
|
||||
Use clientStorage / clientStorageType instead
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">clientStorage</span>** <span className="optional-status">optional</span> `ClientStorage`
|
||||
|
||||
Object where the refresh token will be persisted and read locally.
|
||||
|
||||
Recommended values:
|
||||
|
||||
- `'web'` and `'cookies'`: no value is required
|
||||
- `'react-native'`: `import Storage from @react-native-async-storage/async-storage`
|
||||
- `'cookies'`: `localStorage`
|
||||
- `'custom'`: an object that defines the following methods:
|
||||
- `setItem` or `setItemAsync`
|
||||
- `getItem` or `getItemAsync`
|
||||
- `removeItem`
|
||||
- `'capacitor'`: `import { Storage } from @capacitor/storage`
|
||||
- `'expo-secure-store'`: `import * as SecureStore from 'expo-secure-store'`
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">clientStorageType</span>** <span className="optional-status">optional</span> `ClientStorageType`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: OnTokenChangedFunction
|
||||
sidebar_label: OnTokenChangedFunction
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L117
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L129
|
||||
---
|
||||
|
||||
# `OnTokenChangedFunction`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: Provider
|
||||
sidebar_label: Provider
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/core/src/types.ts#L138
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/core/src/types.ts#L140
|
||||
---
|
||||
|
||||
# `Provider`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: ResetPasswordParams
|
||||
sidebar_label: ResetPasswordParams
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L73
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L85
|
||||
---
|
||||
|
||||
# `ResetPasswordParams`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: SendVerificationEmailParams
|
||||
sidebar_label: SendVerificationEmailParams
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L82
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L94
|
||||
---
|
||||
|
||||
# `SendVerificationEmailParams`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: Session
|
||||
sidebar_label: Session
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L22
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L23
|
||||
---
|
||||
|
||||
# `Session`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: SignInEmailPasswordParams
|
||||
sidebar_label: SignInEmailPasswordParams
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L42
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L54
|
||||
---
|
||||
|
||||
# `SignInEmailPasswordParams`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: SignInParams
|
||||
sidebar_label: SignInParams
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L66
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L78
|
||||
---
|
||||
|
||||
# `SignInParams`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: SignInPasswordlessEmailParams
|
||||
sidebar_label: SignInPasswordlessEmailParams
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L47
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L59
|
||||
---
|
||||
|
||||
# `SignInPasswordlessEmailParams`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: SignInPasswordlessSmsOtpParams
|
||||
sidebar_label: SignInPasswordlessSmsOtpParams
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L57
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L69
|
||||
---
|
||||
|
||||
# `SignInPasswordlessSmsOtpParams`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: SignInPasswordlessSmsParams
|
||||
sidebar_label: SignInPasswordlessSmsParams
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L52
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L64
|
||||
---
|
||||
|
||||
# `SignInPasswordlessSmsParams`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: SignInReponse
|
||||
sidebar_label: SignInReponse
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L102
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L114
|
||||
---
|
||||
|
||||
# `SignInReponse`
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: SignInResponse
|
||||
sidebar_label: SignInResponse
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L45
|
||||
---
|
||||
|
||||
# `SignInResponse`
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">session</span>** <span className="optional-status">required</span> `null` | [`Session`](/reference/docgen/javascript/auth/types/session)
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">mfa</span>** <span className="optional-status">required</span> `null` | `{ ticket: string }`
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">error</span>** <span className="optional-status">required</span> `null` | `ErrorPayload`
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">providerUrl</span>** <span className="optional-status">optional</span> `string`
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">provider</span>** <span className="optional-status">optional</span> `string`
|
||||
|
||||
---
|
||||
@@ -4,7 +4,7 @@ title: SignInWithProviderOptions
|
||||
sidebar_label: SignInWithProviderOptions
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L61
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L73
|
||||
---
|
||||
|
||||
# `SignInWithProviderOptions`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: SignUpEmailPasswordParams
|
||||
sidebar_label: SignUpEmailPasswordParams
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L29
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L31
|
||||
---
|
||||
|
||||
# `SignUpEmailPasswordParams`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: SignUpParams
|
||||
sidebar_label: SignUpParams
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L35
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L37
|
||||
---
|
||||
|
||||
# `SignUpParams`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: SignUpResponse
|
||||
sidebar_label: SignUpResponse
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L37
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/utils/types.ts#L39
|
||||
---
|
||||
|
||||
# `SignUpResponse`
|
||||
|
||||
@@ -4,7 +4,7 @@ title: User
|
||||
sidebar_label: User
|
||||
description: User information
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/core/src/types.ts#L91
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/core/src/types.ts#L93
|
||||
---
|
||||
|
||||
# `User`
|
||||
|
||||
@@ -15,17 +15,15 @@ custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/nhost-js/src/
|
||||
|
||||
**<span className="parameter-name">config</span>** <span className="optional-status">required</span> [`NhostClientConstructorParams`](/reference/docgen/javascript/nhost-js/types/nhost-client-constructor-params)
|
||||
|
||||
| Property | Type | Required | Notes |
|
||||
| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------ | :------: | :---------------------------------------------------------------------------------------------------------------- |
|
||||
| <span className="parameter-name"><span className="light-grey">config.</span>backendUrl</span> | `string` | ✔️ | Nhost backend URL. |
|
||||
| <span className="parameter-name"><span className="light-grey">config.</span>refreshIntervalTime</span> | `number` | | Time interval until token refreshes, in seconds |
|
||||
| <span className="parameter-name"><span className="light-grey">config.</span>clientStorageType</span> | `ClientStorageType` | | Define a way to get information about the refresh token and its exipration date. |
|
||||
| <span className="parameter-name"><span className="light-grey">config.</span>clientStorage</span> | `ClientStorage` | | Object where the refresh token will be persisted and read locally. |
|
||||
| <span className="parameter-name deprecated"><span className="light-grey">config.</span>clientStorageGetter</span> <span className="deprecation-sign" title="Use clientStorage / clientStorageType instead">⚠️</span> | `StorageGetter` | | |
|
||||
| <span className="parameter-name deprecated"><span className="light-grey">config.</span>clientStorageSetter</span> <span className="deprecation-sign" title="Use clientStorage / clientStorageType instead">⚠️</span> | `StorageSetter` | | Define a way to set information about the refresh token and its exipration date. |
|
||||
| <span className="parameter-name"><span className="light-grey">config.</span>autoRefreshToken</span> | `boolean` | | When set to true, will automatically refresh token before it expires |
|
||||
| <span className="parameter-name"><span className="light-grey">config.</span>autoSignIn</span> | `boolean` | | When set to true, will parse the url on startup to check if it contains a refresh token to start the session with |
|
||||
| <span className="parameter-name"><span className="light-grey">config.</span>start</span> | `boolean` | | |
|
||||
| <span className="parameter-name deprecated"><span className="light-grey">config.</span>autoLogin</span> <span className="deprecation-sign" title="@alias autoSignIn - use autoSignIn instead">⚠️</span> | `boolean` | | |
|
||||
| Property | Type | Required | Notes |
|
||||
| :----------------------------------------------------------------------------------------------------- | :------------------ | :------: | :---------------------------------------------------------------------------------------------------------------- |
|
||||
| <span className="parameter-name"><span className="light-grey">config.</span>backendUrl</span> | `string` | ✔️ | Nhost backend URL. |
|
||||
| <span className="parameter-name"><span className="light-grey">config.</span>refreshIntervalTime</span> | `number` | | Time interval until token refreshes, in seconds |
|
||||
| <span className="parameter-name"><span className="light-grey">config.</span>clientStorageType</span> | `ClientStorageType` | | Define a way to get information about the refresh token and its exipration date. |
|
||||
| <span className="parameter-name"><span className="light-grey">config.</span>clientStorage</span> | `ClientStorage` | | Object where the refresh token will be persisted and read locally. |
|
||||
| <span className="parameter-name"><span className="light-grey">config.</span>autoRefreshToken</span> | `boolean` | | When set to true, will automatically refresh token before it expires |
|
||||
| <span className="parameter-name"><span className="light-grey">config.</span>autoSignIn</span> | `boolean` | | When set to true, will parse the url on startup to check if it contains a refresh token to start the session with |
|
||||
| <span className="parameter-name"><span className="light-grey">config.</span>devTools</span> | `boolean` | | Activate devTools e.g. the ability to connect to the xstate inspector |
|
||||
| <span className="parameter-name"><span className="light-grey">config.</span>start</span> | `boolean` | | |
|
||||
|
||||
---
|
||||
|
||||
@@ -17,17 +17,15 @@ Nhost Client
|
||||
|
||||
**<span className="parameter-name">\_\_namedParameters</span>** <span className="optional-status">required</span> [`NhostClientConstructorParams`](/reference/docgen/javascript/nhost-js/types/nhost-client-constructor-params)
|
||||
|
||||
| Property | Type | Required | Notes |
|
||||
| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------ | :------: | :---------------------------------------------------------------------------------------------------------------- |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>backendUrl</span> | `string` | ✔️ | Nhost backend URL. |
|
||||
| <span className="parameter-name deprecated"><span className="light-grey">\_\_namedParameters.</span>autoLogin</span> <span className="deprecation-sign" title="@alias autoSignIn - use autoSignIn instead">⚠️</span> | `boolean` | | |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>start</span> | `boolean` | | |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>autoSignIn</span> | `boolean` | | When set to true, will parse the url on startup to check if it contains a refresh token to start the session with |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>autoRefreshToken</span> | `boolean` | | When set to true, will automatically refresh token before it expires |
|
||||
| <span className="parameter-name deprecated"><span className="light-grey">\_\_namedParameters.</span>clientStorageSetter</span> <span className="deprecation-sign" title="Use clientStorage / clientStorageType instead">⚠️</span> | `StorageSetter` | | Define a way to set information about the refresh token and its exipration date. |
|
||||
| <span className="parameter-name deprecated"><span className="light-grey">\_\_namedParameters.</span>clientStorageGetter</span> <span className="deprecation-sign" title="Use clientStorage / clientStorageType instead">⚠️</span> | `StorageGetter` | | |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>clientStorage</span> | `ClientStorage` | | Object where the refresh token will be persisted and read locally. |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>clientStorageType</span> | `ClientStorageType` | | Define a way to get information about the refresh token and its exipration date. |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>refreshIntervalTime</span> | `number` | | Time interval until token refreshes, in seconds |
|
||||
| Property | Type | Required | Notes |
|
||||
| :------------------------------------------------------------------------------------------------------------------ | :------------------ | :------: | :---------------------------------------------------------------------------------------------------------------- |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>backendUrl</span> | `string` | ✔️ | Nhost backend URL. |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>start</span> | `boolean` | | |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>devTools</span> | `boolean` | | Activate devTools e.g. the ability to connect to the xstate inspector |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>autoSignIn</span> | `boolean` | | When set to true, will parse the url on startup to check if it contains a refresh token to start the session with |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>autoRefreshToken</span> | `boolean` | | When set to true, will automatically refresh token before it expires |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>clientStorage</span> | `ClientStorage` | | Object where the refresh token will be persisted and read locally. |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>clientStorageType</span> | `ClientStorageType` | | Define a way to get information about the refresh token and its exipration date. |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>refreshIntervalTime</span> | `number` | | Time interval until token refreshes, in seconds |
|
||||
|
||||
---
|
||||
|
||||
@@ -39,23 +39,17 @@ Define a way to get information about the refresh token and its exipration date.
|
||||
|
||||
Object where the refresh token will be persisted and read locally.
|
||||
|
||||
---
|
||||
Recommended values:
|
||||
|
||||
**<span className="parameter-name deprecated">clientStorageGetter</span>** <span className="optional-status">optional</span> `StorageGetter`
|
||||
|
||||
:::caution Deprecated
|
||||
Use clientStorage / clientStorageType instead
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name deprecated">clientStorageSetter</span>** <span className="optional-status">optional</span> `StorageSetter`
|
||||
|
||||
Define a way to set information about the refresh token and its exipration date.
|
||||
|
||||
:::caution Deprecated
|
||||
Use clientStorage / clientStorageType instead
|
||||
:::
|
||||
- `'web'` and `'cookies'`: no value is required
|
||||
- `'react-native'`: `import Storage from @react-native-async-storage/async-storage`
|
||||
- `'cookies'`: `localStorage`
|
||||
- `'custom'`: an object that defines the following methods:
|
||||
- `setItem` or `setItemAsync`
|
||||
- `getItem` or `getItemAsync`
|
||||
- `removeItem`
|
||||
- `'capacitor'`: `import { Storage } from @capacitor/storage`
|
||||
- `'expo-secure-store'`: `import * as SecureStore from 'expo-secure-store'`
|
||||
|
||||
---
|
||||
|
||||
@@ -71,14 +65,12 @@ When set to true, will parse the url on startup to check if it contains a refres
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">devTools</span>** <span className="optional-status">optional</span> `boolean`
|
||||
|
||||
Activate devTools e.g. the ability to connect to the xstate inspector
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">start</span>** <span className="optional-status">optional</span> `boolean`
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name deprecated">autoLogin</span>** <span className="optional-status">optional</span> `boolean`
|
||||
|
||||
:::caution Deprecated
|
||||
@alias autoSignIn - use autoSignIn instead
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
@@ -11,6 +11,8 @@ custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-storag
|
||||
|
||||
Use `nhost.storage.upload` to upload a file. The `file` must be of type [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File).
|
||||
|
||||
If no `bucket` is specified the `default` bucket will be used.
|
||||
|
||||
```ts
|
||||
await nhost.storage.upload({ file })
|
||||
```
|
||||
|
||||
@@ -15,12 +15,12 @@ custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/nextjs/src/in
|
||||
|
||||
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> [`NhostNextClientConstructorParams`](/reference/docgen/nextjs/types/nhost-next-client-constructor-params)
|
||||
|
||||
| Property | Type | Required | Notes |
|
||||
| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :-------- | :------: | :---------------------------------------------------------------------------------------------------------------- |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>backendUrl</span> | `string` | ✔️ | Nhost backend URL. |
|
||||
| <span className="parameter-name deprecated"><span className="light-grey">params.</span>autoLogin</span> <span className="deprecation-sign" title="@alias autoSignIn - use autoSignIn instead">⚠️</span> | `boolean` | | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>autoSignIn</span> | `boolean` | | When set to true, will parse the url on startup to check if it contains a refresh token to start the session with |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>autoRefreshToken</span> | `boolean` | | When set to true, will automatically refresh token before it expires |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>refreshIntervalTime</span> | `number` | | Time interval until token refreshes, in seconds |
|
||||
| Property | Type | Required | Notes |
|
||||
| :----------------------------------------------------------------------------------------------------- | :-------- | :------: | :---------------------------------------------------------------------------------------------------------------- |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>backendUrl</span> | `string` | ✔️ | Nhost backend URL. |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>devTools</span> | `boolean` | | Activate devTools e.g. the ability to connect to the xstate inspector |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>autoSignIn</span> | `boolean` | | When set to true, will parse the url on startup to check if it contains a refresh token to start the session with |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>autoRefreshToken</span> | `boolean` | | When set to true, will automatically refresh token before it expires |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>refreshIntervalTime</span> | `number` | | Time interval until token refreshes, in seconds |
|
||||
|
||||
---
|
||||
|
||||
@@ -4,7 +4,7 @@ title: useAccessToken()
|
||||
sidebar_label: useAccessToken()
|
||||
slug: /reference/nextjs/use-access-token
|
||||
description: Use `useAccessToken` to get the access token of the user.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/react/src/hooks/common.ts#L144
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/react/src/hooks/common.ts#L119
|
||||
---
|
||||
|
||||
# `useAccessToken()`
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user