example: Nhost with auth and realtime graphql example added (#22493)
This commit is contained in:
parent
460c7c7ddc
commit
a78e904fc8
13 changed files with 745 additions and 0 deletions
|
@ -0,0 +1,2 @@
|
|||
NEXT_PUBLIC_GRAPHQL_URL=https://hasura-[project-id].nhost.app/v1/graphql
|
||||
NEXT_PUBLIC_BACKEND_URL=https://backend-[project-id].nhost.app
|
34
examples/with-nhost-auth-realtime-graphql/.gitignore
vendored
Normal file
34
examples/with-nhost-auth-realtime-graphql/.gitignore
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
61
examples/with-nhost-auth-realtime-graphql/README.md
Normal file
61
examples/with-nhost-auth-realtime-graphql/README.md
Normal file
|
@ -0,0 +1,61 @@
|
|||
# Auth & Realtime GraphQL Example Using Next.js and Nhost
|
||||
|
||||
This example showcases Next.js as the frontend using [Nhost](https://nhost.io/) as the backend.
|
||||
|
||||
## Demo
|
||||
|
||||
### [https://nhost-nextjs-example.vercel.app/](https://nhost-nextjs-example.vercel.app/)
|
||||
|
||||
## Deploy Your Own
|
||||
|
||||
Once you have created a Nhost project and have access to [the environment variables you'll need](#step-4-add-environment-variables), deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):
|
||||
|
||||
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-nhost-auth-realtime-graphql&project-name=with-nhost-auth-realtime-graphql&repository-name=with-nhost-auth-realtime-graphql&env=NEXT_PUBLIC_GRAPHQL_URL,NEXT_PUBLIC_BACKEND_URL&envDescription=Enter%20your%20Nhost%20project%27s%20URLs)
|
||||
|
||||
## How to use
|
||||
|
||||
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
|
||||
|
||||
```bash
|
||||
npx create-next-app --example nhost nhost-app
|
||||
# or
|
||||
yarn create next-app --example nhost nhost-app
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Step 1. Create an account and a project on Nhost
|
||||
|
||||
[Create an account and project on Nhost](https://console.nhost.io).
|
||||
|
||||
### Step 2. Create `items` database
|
||||
|
||||
Go to your project's Hasura console. Go to the **DATA** tab in the top menu and click **SQL** in the bottom left menu.
|
||||
|
||||
Then copy the content from `setup/data.sql` in this example and paste it in the **Raw SQL** form in the Hasura Console. Make sure **Track this** is checked and click **Run!**
|
||||
|
||||
### Step 3. Add API metadata
|
||||
|
||||
Again, in the Hasura console, click on the **gearwheel** (settings) in the top right menu. Click on **Import metadata** and select the file `setup/hasura-metadata.json` in this repository.
|
||||
|
||||
### Step 4. Add environment variables
|
||||
|
||||
Copy `.env.local.example` to `.env.local` and update the two URLs with your Nhost project URLs. You find the URLs in the Nhost console dashboard of your project.
|
||||
|
||||
### Step 5. Run Next.js in development mode
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run dev
|
||||
|
||||
# or
|
||||
|
||||
yarn install
|
||||
yarn dev
|
||||
```
|
||||
|
||||
Your app should be up and running on [http://localhost:3000](http://localhost:3000)! If it doesn't work, post on [GitHub discussions](https://github.com/vercel/next.js/discussions).
|
||||
|
||||
### Step 6. Deploy on Vercel
|
||||
|
||||
You can deploy this app to the cloud with [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
|
|
@ -0,0 +1,22 @@
|
|||
/* eslint-disable react-hooks/rules-of-hooks */
|
||||
import { useRouter } from 'next/router'
|
||||
import { useAuth } from '@nhost/react-auth'
|
||||
|
||||
export function PrivateRoute(Component) {
|
||||
return (props) => {
|
||||
const router = useRouter()
|
||||
const { signedIn } = useAuth()
|
||||
|
||||
// wait to see if the user is logged in or not.
|
||||
if (signedIn === null) {
|
||||
return <div>Checking auth...</div>
|
||||
}
|
||||
|
||||
if (!signedIn) {
|
||||
router.push('/login')
|
||||
return <div>Redirecting...</div>
|
||||
}
|
||||
|
||||
return <Component {...props} />
|
||||
}
|
||||
}
|
20
examples/with-nhost-auth-realtime-graphql/package.json
Normal file
20
examples/with-nhost-auth-realtime-graphql/package.json
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "with-nhost-auth-realtime-graphql",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/client": "3.3.11",
|
||||
"@nhost/react-apollo": "1.0.7",
|
||||
"@nhost/react-auth": "1.0.5",
|
||||
"graphql": "15.5.0",
|
||||
"next": "10.0.7",
|
||||
"nhost-js-sdk": "3.0.0-16",
|
||||
"react": "17.0.1",
|
||||
"react-dom": "17.0.1"
|
||||
}
|
||||
}
|
19
examples/with-nhost-auth-realtime-graphql/pages/_app.js
Normal file
19
examples/with-nhost-auth-realtime-graphql/pages/_app.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
import { NhostAuthProvider } from '@nhost/react-auth'
|
||||
import { NhostApolloProvider } from '@nhost/react-apollo'
|
||||
|
||||
import { nhost } from '../utils/nhost'
|
||||
|
||||
function MyApp({ Component, pageProps }) {
|
||||
return (
|
||||
<NhostAuthProvider auth={nhost.auth}>
|
||||
<NhostApolloProvider
|
||||
auth={nhost.auth}
|
||||
gqlEndpoint={process.env.NEXT_PUBLIC_GRAPHQL_URL}
|
||||
>
|
||||
<Component {...pageProps} />
|
||||
</NhostApolloProvider>
|
||||
</NhostAuthProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default MyApp
|
|
@ -0,0 +1,3 @@
|
|||
export default function handler(req, res) {
|
||||
res.status(200).json({ name: 'John Doe' })
|
||||
}
|
128
examples/with-nhost-auth-realtime-graphql/pages/index.js
Normal file
128
examples/with-nhost-auth-realtime-graphql/pages/index.js
Normal file
|
@ -0,0 +1,128 @@
|
|||
import { useState } from 'react'
|
||||
import { useSubscription, useMutation, gql } from '@apollo/client'
|
||||
import { PrivateRoute } from '../components/private-route'
|
||||
import { nhost } from '../utils/nhost'
|
||||
|
||||
const INSERT_ITEM = gql`
|
||||
mutation insertItem($item: items_insert_input!) {
|
||||
insert_items_one(object: $item) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const S_GET_ITEMS = gql`
|
||||
subscription sGetItems {
|
||||
items {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const DELETE_ITEM = gql`
|
||||
mutation deleteItem($item_id: uuid!) {
|
||||
delete_items_by_pk(id: $item_id) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
function InsertItem() {
|
||||
const [name, setName] = useState('')
|
||||
const [insertItem] = useMutation(INSERT_ITEM)
|
||||
|
||||
async function handleFormSubmit(e) {
|
||||
e.preventDefault()
|
||||
try {
|
||||
insertItem({
|
||||
variables: {
|
||||
item: {
|
||||
name,
|
||||
},
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
return alert('Error inserting item')
|
||||
}
|
||||
|
||||
setName('')
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ padding: '10px' }}>
|
||||
<form onSubmit={handleFormSubmit}>
|
||||
<div>
|
||||
<input
|
||||
type="name"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<button type="submit">Insert item</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function ListItems() {
|
||||
const { loading, error, data } = useSubscription(S_GET_ITEMS)
|
||||
const [deleteItem] = useMutation(DELETE_ITEM)
|
||||
|
||||
async function handleDeleteItem(itemId) {
|
||||
try {
|
||||
deleteItem({
|
||||
variables: {
|
||||
item_id: itemId,
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
return alert('Error deleting item')
|
||||
}
|
||||
}
|
||||
|
||||
if (loading && !data) {
|
||||
return <div>Loading...</div>
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return <div>Error loading items</div>
|
||||
}
|
||||
|
||||
const { items } = data
|
||||
|
||||
return (
|
||||
<div style={{ padding: '10px' }}>
|
||||
{items.map((item) => {
|
||||
return (
|
||||
<li key={item.id}>
|
||||
{item.name} [
|
||||
<span onClick={() => handleDeleteItem(item.id)}>delete</span>]
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function Home() {
|
||||
return (
|
||||
<div>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<pre>{nhost.auth.user().display_name}</pre>
|
||||
<div style={{ paddingLeft: '10px' }}>
|
||||
<button onClick={() => nhost.auth.logout()}>logout</button>
|
||||
</div>
|
||||
</div>
|
||||
<h1>Dashboard</h1>
|
||||
<InsertItem />
|
||||
<ListItems />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PrivateRoute(Home)
|
54
examples/with-nhost-auth-realtime-graphql/pages/login.js
Normal file
54
examples/with-nhost-auth-realtime-graphql/pages/login.js
Normal file
|
@ -0,0 +1,54 @@
|
|||
import { useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import Link from 'next/link'
|
||||
|
||||
import { nhost } from '../utils/nhost'
|
||||
|
||||
export default function Login() {
|
||||
const router = useRouter()
|
||||
const [email, setEmail] = useState('')
|
||||
const [password, setPassword] = useState('')
|
||||
|
||||
async function handleLogin(e) {
|
||||
e.preventDefault()
|
||||
|
||||
try {
|
||||
await nhost.auth.login({ email, password })
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
return alert('failed to login')
|
||||
}
|
||||
|
||||
router.push('/')
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<form onSubmit={handleLogin}>
|
||||
<div>
|
||||
<input
|
||||
placeholder="Email"
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<button type="submit">Login</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div>
|
||||
<Link href="/register">Register</Link>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
71
examples/with-nhost-auth-realtime-graphql/pages/register.js
Normal file
71
examples/with-nhost-auth-realtime-graphql/pages/register.js
Normal file
|
@ -0,0 +1,71 @@
|
|||
import { useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import Link from 'next/link'
|
||||
|
||||
import { nhost } from '../utils/nhost'
|
||||
|
||||
export default function Login() {
|
||||
const router = useRouter()
|
||||
const [displayName, setDisplayName] = useState('')
|
||||
const [email, setEmail] = useState('')
|
||||
const [password, setPassword] = useState('')
|
||||
|
||||
async function handleLogin(e) {
|
||||
e.preventDefault()
|
||||
|
||||
try {
|
||||
await nhost.auth.register({
|
||||
email,
|
||||
password,
|
||||
options: {
|
||||
userData: {
|
||||
display_name: displayName,
|
||||
},
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
return alert('failed to register')
|
||||
}
|
||||
|
||||
router.push('/')
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<form onSubmit={handleLogin}>
|
||||
<div>
|
||||
<input
|
||||
placeholder="Name"
|
||||
type="text"
|
||||
value={displayName}
|
||||
onChange={(e) => setDisplayName(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
placeholder="Email"
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<button type="submit">Register</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div>
|
||||
<Link href="/login">Login</Link>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
16
examples/with-nhost-auth-realtime-graphql/setup/data.sql
Normal file
16
examples/with-nhost-auth-realtime-graphql/setup/data.sql
Normal file
|
@ -0,0 +1,16 @@
|
|||
CREATE TABLE public.items (
|
||||
id uuid DEFAULT public.gen_random_uuid() NOT NULL,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
name text NOT NULL,
|
||||
user_id uuid NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE
|
||||
ONLY public.items
|
||||
ADD
|
||||
CONSTRAINT items_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE
|
||||
ONLY public.items
|
||||
ADD
|
||||
CONSTRAINT items_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON UPDATE CASCADE ON DELETE CASCADE;
|
|
@ -0,0 +1,310 @@
|
|||
{
|
||||
"version": 2,
|
||||
"tables": [
|
||||
{
|
||||
"table": {
|
||||
"schema": "auth",
|
||||
"name": "account_providers"
|
||||
},
|
||||
"object_relationships": [
|
||||
{
|
||||
"name": "account",
|
||||
"using": {
|
||||
"foreign_key_constraint_on": "account_id"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "provider",
|
||||
"using": {
|
||||
"foreign_key_constraint_on": "auth_provider"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": {
|
||||
"schema": "auth",
|
||||
"name": "account_roles"
|
||||
},
|
||||
"object_relationships": [
|
||||
{
|
||||
"name": "account",
|
||||
"using": {
|
||||
"foreign_key_constraint_on": "account_id"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "roleByRole",
|
||||
"using": {
|
||||
"foreign_key_constraint_on": "role"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": {
|
||||
"schema": "auth",
|
||||
"name": "accounts"
|
||||
},
|
||||
"object_relationships": [
|
||||
{
|
||||
"name": "role",
|
||||
"using": {
|
||||
"foreign_key_constraint_on": "default_role"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "user",
|
||||
"using": {
|
||||
"foreign_key_constraint_on": "user_id"
|
||||
}
|
||||
}
|
||||
],
|
||||
"array_relationships": [
|
||||
{
|
||||
"name": "account_providers",
|
||||
"using": {
|
||||
"foreign_key_constraint_on": {
|
||||
"column": "account_id",
|
||||
"table": {
|
||||
"schema": "auth",
|
||||
"name": "account_providers"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "account_roles",
|
||||
"using": {
|
||||
"foreign_key_constraint_on": {
|
||||
"column": "account_id",
|
||||
"table": {
|
||||
"schema": "auth",
|
||||
"name": "account_roles"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "refresh_tokens",
|
||||
"using": {
|
||||
"foreign_key_constraint_on": {
|
||||
"column": "account_id",
|
||||
"table": {
|
||||
"schema": "auth",
|
||||
"name": "refresh_tokens"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"select_permissions": [
|
||||
{
|
||||
"role": "me",
|
||||
"permission": {
|
||||
"columns": ["email", "id"],
|
||||
"filter": {
|
||||
"user_id": {
|
||||
"_eq": "X-Hasura-User-Id"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": {
|
||||
"schema": "auth",
|
||||
"name": "providers"
|
||||
},
|
||||
"array_relationships": [
|
||||
{
|
||||
"name": "account_providers",
|
||||
"using": {
|
||||
"foreign_key_constraint_on": {
|
||||
"column": "auth_provider",
|
||||
"table": {
|
||||
"schema": "auth",
|
||||
"name": "account_providers"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": {
|
||||
"schema": "auth",
|
||||
"name": "refresh_tokens"
|
||||
},
|
||||
"object_relationships": [
|
||||
{
|
||||
"name": "account",
|
||||
"using": {
|
||||
"foreign_key_constraint_on": "account_id"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": {
|
||||
"schema": "auth",
|
||||
"name": "roles"
|
||||
},
|
||||
"array_relationships": [
|
||||
{
|
||||
"name": "account_roles",
|
||||
"using": {
|
||||
"foreign_key_constraint_on": {
|
||||
"column": "role",
|
||||
"table": {
|
||||
"schema": "auth",
|
||||
"name": "account_roles"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "accounts",
|
||||
"using": {
|
||||
"foreign_key_constraint_on": {
|
||||
"column": "default_role",
|
||||
"table": {
|
||||
"schema": "auth",
|
||||
"name": "accounts"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": {
|
||||
"schema": "public",
|
||||
"name": "items"
|
||||
},
|
||||
"object_relationships": [
|
||||
{
|
||||
"name": "user",
|
||||
"using": {
|
||||
"foreign_key_constraint_on": "user_id"
|
||||
}
|
||||
}
|
||||
],
|
||||
"insert_permissions": [
|
||||
{
|
||||
"role": "user",
|
||||
"permission": {
|
||||
"check": {
|
||||
"user_id": {
|
||||
"_eq": "X-Hasura-User-Id"
|
||||
}
|
||||
},
|
||||
"set": {
|
||||
"user_id": "x-hasura-user-id"
|
||||
},
|
||||
"columns": ["name"],
|
||||
"backend_only": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"select_permissions": [
|
||||
{
|
||||
"role": "user",
|
||||
"permission": {
|
||||
"columns": ["id", "created_at", "name", "user_id"],
|
||||
"filter": {
|
||||
"user_id": {
|
||||
"_eq": "X-Hasura-User-Id"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"delete_permissions": [
|
||||
{
|
||||
"role": "user",
|
||||
"permission": {
|
||||
"filter": {
|
||||
"user_id": {
|
||||
"_eq": "X-Hasura-User-Id"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": {
|
||||
"schema": "public",
|
||||
"name": "users"
|
||||
},
|
||||
"object_relationships": [
|
||||
{
|
||||
"name": "account",
|
||||
"using": {
|
||||
"manual_configuration": {
|
||||
"remote_table": {
|
||||
"schema": "auth",
|
||||
"name": "accounts"
|
||||
},
|
||||
"column_mapping": {
|
||||
"id": "user_id"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"array_relationships": [
|
||||
{
|
||||
"name": "items",
|
||||
"using": {
|
||||
"foreign_key_constraint_on": {
|
||||
"column": "user_id",
|
||||
"table": {
|
||||
"schema": "public",
|
||||
"name": "items"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"select_permissions": [
|
||||
{
|
||||
"role": "me",
|
||||
"permission": {
|
||||
"columns": [
|
||||
"id",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"display_name",
|
||||
"avatar_url"
|
||||
],
|
||||
"filter": {
|
||||
"id": {
|
||||
"_eq": "X-Hasura-User-Id"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"permission": {
|
||||
"columns": [
|
||||
"id",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"display_name",
|
||||
"avatar_url"
|
||||
],
|
||||
"filter": {
|
||||
"id": {
|
||||
"_eq": "X-Hasura-User-Id"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
5
examples/with-nhost-auth-realtime-graphql/utils/nhost.js
Normal file
5
examples/with-nhost-auth-realtime-graphql/utils/nhost.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { createClient } from 'nhost-js-sdk'
|
||||
|
||||
export const nhost = createClient({
|
||||
baseURL: process.env.NEXT_PUBLIC_BACKEND_URL,
|
||||
})
|
Loading…
Reference in a new issue