Quick Start

Share your feedback
Reach out to us with feedback and suggestions to improve the Wix Headless experience, and join the Headless channel of the Devs on Wix Discord community to discuss features and connect with our growing community of developers.

Follow this quick start tutorial to get up and running with your first Headless project.

This tutorial walks you through the project setup process and builds a simple site that uses tokens to maintain persistent visitor sessions and to authenticate site members.

You can use the code described here as a springboard for your own project. After building the foundation here to handle visitors and members, you can continue your development by making use of the various modules in the Wix Javascript SDK.

For detailed instructions for managing visitors and members, see Handle Visitors, Handle Members with Managed Login, and Handle Members with Custom Login.

This tutorial shows you how to implement:

  • A React component that handles login and logout by redirecting the visitor to a Wix-managed page.
  • A callback page that verifies login and saves member tokens in a cookie.
  • Next.js middleware that checks for an existing member or visitor token and generates a new visitor token if one is not found.

The tutorial is based on the Wix Headless example site. You can test out the live example site, or fork the site's code repo to use as a starting point for your own site or app.

This implementation focuses on simplicity and understandability, rather than feature richness, performance or completeness. For details about additional functionality, see the API Reference. Looking for a more comprehensive example site integrating Wix Headless APIs? Check out our starter templates.

Note: The code in this tutorial is written in JSX, but you can use the SDK in any JavaScript environment.

Implementing the session management flow includes the following steps:

  1. Set up the Wix Headless environment.
  2. Create a login component.
  3. Create a callback page.
  4. Create middleware for managing tokens.

Step 1: Set up the Wix Headless environment

Before using the SDK, there are a few things you need to set up on your Wix account and in your external site or app's coding environment.

To set up the Wix Headless environment, follow these steps:

  1. If you haven't already, create a project.
    When prompted to add functionalities to your new project, select whichever business solutions your project needs.
  2. Set up authorization for your site by creating and configuring an OAuth app.
  3. Install the SDK client and relevant SDK module packages by running the following commands:
    For NPM:
    Copy
    1
    npm install @wix/sdk
    2
    npm install @wix/members
    For Yarn:
    Copy
    1
    yarn add @wix/sdk
    2
    yarn add @wix/members
  4. Install the react package to handle UI rendering, the js-cookie package to handle session cookies, and the next/server package with helper functions for Next.js middleware.
    For NPM:
    Copy
    1
    npm install react
    2
    npm install js-cookie
    3
    npm install next/server
    For Yarn:
    Copy
    1
    yarn add react
    2
    yarn add js-cookie
    3
    yarn add next/server

Step 2: Create a login component

Follow these steps to create a React component that handles login and logout by redirecting the visitor to a Wix-managed page.

1. Import the SDK modules and create an SDK client

To set up the code file for the login component, follow these steps:

  1. Add the following import statements to the top of your code file:

    Copy
    1
    import { createClient, OAuthStrategy } from '@wix/sdk';
    2
    import { members } from '@wix/members';
    3
    import { useEffect, useState } from 'react';
    4
    import Cookies from 'js-cookie';
  2. Create an SDK client by adding the following code to your code file. Replace the value for clientId with your OAuth app's client ID. You can find the ID in your project's Headless Settings menu.

    The value for tokens is the 'session' cookie on the visitor's browser. It's used to make calls to the Wix API. This way, you can maintain previous visitor sessions. If a token has already been generated for the visitor, this token is used.

    Copy
    1
    const myWixClient = createClient({
    2
    modules: { members },
    3
    auth: OAuthStrategy({
    4
    clientId: `<YOUR-CLIENT-ID>`,
    5
    tokens: JSON.parse(Cookies.get('session') || null),
    6
    }),
    7
    });

2. Create a React component and a state variable

The logic for our example login request flow is contained in a React component called LoginBar. To create the component, follow these steps:

  1. Define the component function as a default export in your code file:

    Copy
    1
    export default function LoginBar() {}
  2. Define a state variable by adding the following code in the component function:

    Copy
    1
    const [member, setMember] = useState([]);

    In the steps that follow, the member state variable stores a visitor's data if they are a logged-in site member.

3. Define functions to handle member sessions

Add the following 3 functions for handling member sessions to the LoginBar component:

  1. fetchMember() - Uses the SDK client's auth.loggedIn() function to check if the current site visitor is a logged-in site member. If they are, the rendered UI is updated with the member's details. This function runs when the component is mounted.

    Copy
    1
    async function fetchMember() {
    2
    const { member } = myWixClient.auth.loggedIn()
    3
    ? await myWixClient.members.getCurrentMember()
    4
    : {};
    5
    setMember(member || undefined);
    6
    }
  2. login() - Uses the SDK client's auth.generateOAuthData() and auth.getAuthUrl() functions to log in a site visitor. This function runs when a Login button in the rendered UI is clicked.

    Copy
    1
    async function login() {
    2
    const data = myWixClient.auth.generateOAuthData(
    3
    `${window.location.origin}/login-callback`,
    4
    window.location.href
    5
    );
    6
    localStorage.setItem('oauthRedirectData', JSON.stringify(data));
    7
    const { authUrl } = await myWixClient.auth.getAuthUrl(data);
    8
    window.location = authUrl;
    9
    }

    The SDK client's auth.generateOAuthData() function generates the data needed for authorization, which is saved in local storage with the key oauthRedirectData. When the Wix-managed authentication process is over, Wix redirects the visitor to the URL provided in redirectUri. The auth.getAuthUrl() function returns a URL for a Wix-managed authentication page called authUrl.

  3. logout() - Uses the SDK client's auth.logout() function to log out a site member and remove the session cookie from their browser. This function runs when a Logout button in the rendered UI is clicked.

    Copy
    1
    async function logout() {
    2
    const { logoutUrl } = await myWixClient.auth.logout(window.location.href);
    3
    Cookies.remove('session');
    4
    window.location = logoutUrl;
    5
    }

4. Add the useEffect hook

Add the following code to the LoginBar component to run the fetchMember() function after the component is rendered. This ensures that member data is retrieved when the component mounts.

Copy
1
useEffect(() => {
2
fetchMember();
3
}, []);

5. Render the UI

Add the following code to the LoginBar component function's return statement to render the UI.

Copy
1
return (
2
<div>
3
{member !== null && (
4
<section
5
onClick={() => (myWixClient.auth.loggedIn() ? logout() : login())}
6
>
7
<h3>
8
Hello{' '}
9
{myWixClient.auth.loggedIn()
10
? member.profile?.nickname || member.profile?.slug || ''
11
: 'visitor'}
12
,
13
</h3>
14
<span>{myWixClient.auth.loggedIn() ? 'Logout' : 'Login'}</span>
15
</section>
16
)}
17
</div>
18
);

The UI displays the following:

  • If no member is logged in: Hello visitor and a Login link.
  • If a member is logged in: Hello, <USER_NAME> and a Logout link.

Step 3: Create a callback page

Follow these steps to create a callback page for Wix to redirect the visitor to after handling authentication.

1. Import the SDK modules and create an SDK client

To set up the code file for the callback page, follow these steps:

  1. Add the following import statements to the top of your code file:

    Copy
    1
    import Cookies from 'js-cookie';
    2
    import { useEffect, useState } from 'react';
    3
    import { createClient, OAuthStrategy } from '@wix/sdk';
  2. Create an SDK client by adding the following code to your code file:

    Copy
    1
    const myWixClient = createClient({
    2
    auth: OAuthStrategy({
    3
    clientId: `<YOUR-CLIENT-ID>`,
    4
    tokens: JSON.parse(Cookies.get('session') || null),
    5
    }),
    6
    });

2. Create a React component and state variables

The logic for our example login request flow is contained in a React component called LoginCallback. To create the component, follow these steps:

  1. Define the component function as a default export in your code file:

    Copy
    1
    export default function LoginCallback() {}
  2. Define state variables by adding the following code in the component function:

    Copy
    1
    const [nextPage, setNextPage] = useState(null);
    2
    const [errorMessage, setErrorMessage] = useState(null);

    In the steps that follow, the nextPage state variable stores the URL of the page to redirect the visitor to, and the errorMessage state variable stores the error received if there is an error generating a member token.

3. Define a function to verify login

Add the following function to the LoginCallback component. This function first retrieves the authorization data saved in local storage by the Login component. Then it retrieves the authorization code and state from the callback page's URL using auth.parseFromUrl(). Using this data, it calls auth.getMemberTokens() to generate access and refresh tokens, which it stores in the 'session' cookie. It then redirects the visitor to the page specified in data.originalUri if it exists, or otherwise to /.

Copy
1
async function verifyLogin() {
2
const data = JSON.parse(localStorage.getItem('oauthRedirectData'));
3
localStorage.removeItem('oauthRedirectData');
4
5
try {
6
const { code, state } = myWixClient.auth.parseFromUrl();
7
let tokens = await myWixClient.auth.getMemberTokens(code, state, data);
8
while (!tokens?.refreshToken?.value) {
9
tokens = await myWixClient.auth.getMemberTokens(code, state, data);
10
}
11
Cookies.set('session', JSON.stringify(tokens));
12
window.location = data?.originalUri || '/';
13
} catch (e) {
14
setNextPage(data?.originalUri || '/');
15
setErrorMessage(e.toString());
16
}
17
}

4. Add the useEffect hook

Add the following code to the LoginCallback component to run the verifyLogin() function after the component is rendered. This ensures that tokens are stored when the component mounts.

Copy
1
useEffect(() => {
2
verifyLogin();
3
}, []);

5. Render the UI

Add the following code to the LoginCallback component function's return statement to render the UI.

Copy
1
return (
2
<article>
3
{errorMessage && (
4
<>
5
<span>{errorMessage}</span>
6
<br />
7
<br />
8
</>
9
)}
10
{nextPage ? <a href={nextPage}>Continue</a> : <>Loading...</>}
11
</article>
12
);

The UI displays the following before redirecting the visitor:

  • If there was an error, errorMessage is displayed.
  • If login was verified, a link to the next page with the text Continue is rendered, along with the text Loading....

Step 4: Create middleware for managing tokens

Once you've implemented a login component and a callback page, follow these steps to create Next.js middleware to check a visitor's session status when loading every page.

1. Import the SDK modules

To set up the code file for the session management middleware, follow these steps:

  1. Add the following import statements to the top of your code file:

    Copy
    1
    import { createClient, OAuthStrategy } from '@wix/sdk';
    2
    import { NextResponse } from '/next/server';

2. Create a middleware function

The logic for our middleware is contained in a function called middleware(). This function checks if a 'session' cookie already exists in the page request. If the cookie isn't found, it generates new visitor tokens using auth.generateVisitorTokens() and stores them in a 'session' cookie to create a new anonymous session which persists when the visitor uses the site from the same browser.
Implement this function as follows:

Copy
1
export async function middleware(request) {
2
if (!request.cookies.get('session')) {
3
const response = NextResponse.next();
4
const myWixClient = createClient({
5
auth: OAuthStrategy({ clientId: `<YOUR-CLIENT-ID>` }),
6
});
7
response.cookies.set(
8
'session',
9
JSON.stringify(await myWixClient.auth.generateVisitorTokens())
10
);
11
return response;
12
}
13
}

Complete code examples

You can use the following full code examples as a starting point for developing your own site:

Login component

Copy
1
import Cookies from 'js-cookie';
2
import { useEffect, useState } from 'react';
3
4
import { createClient, OAuthStrategy } from '@wix/sdk';
5
import { members } from '@wix/members';
6
7
const myWixClient = createClient({
8
modules: { members },
9
auth: OAuthStrategy({
10
clientId: `10c1663b-2cdf-47c5-a3ef-30c2e8543849`,
11
tokens: JSON.parse(Cookies.get('session') || null),
12
}),
13
});
14
15
export default function LoginBar() {
16
const [member, setMember] = useState(null);
17
18
async function fetchMember() {
19
const { member } = myWixClient.auth.loggedIn()
20
? await myWixClient.members.getCurrentMember()
21
: {};
22
setMember(member || undefined);
23
}
24
25
async function login() {
26
const data = myWixClient.auth.generateOAuthData(
27
`${window.location.origin}/login-callback`,
28
window.location.href
29
);
30
localStorage.setItem('oauthRedirectData', JSON.stringify(data));
31
const { authUrl } = await myWixClient.auth.getAuthUrl(data);
32
window.location = authUrl; // wix auth will send the user back to the callback page (login-callback.js)
33
}
34
35
async function logout() {
36
const { logoutUrl } = await myWixClient.auth.logout(window.location.href);
37
Cookies.remove('session');
38
window.location = logoutUrl;
39
}
40
41
useEffect(() => {
42
fetchMember();
43
}, []);
44
45
return (
46
<div>
47
{member !== null && (
48
<section
49
onClick={() => (myWixClient.auth.loggedIn() ? logout() : login())}
50
>
51
<h3>
52
Hello{' '}
53
{myWixClient.auth.loggedIn()
54
? member.profile?.nickname || member.profile?.slug || ''
55
: 'visitor'}
56
,
57
</h3>
58
<span>{myWixClient.auth.loggedIn() ? 'Logout' : 'Login'}</span>
59
</section>
60
)}
61
</div>
62
);
63
}

Callback page

Copy
1
import Cookies from 'js-cookie';
2
import { useEffect, useState } from 'react';
3
import { createClient, OAuthStrategy } from '@wix/sdk';
4
5
const myWixClient = createClient({
6
auth: OAuthStrategy({
7
clientId: `10c1663b-2cdf-47c5-a3ef-30c2e8543849`,
8
tokens: JSON.parse(Cookies.get('session') || null),
9
}),
10
});
11
12
export default function LoginCallback() {
13
const [nextPage, setNextPage] = useState(null);
14
const [errorMessage, setErrorMessage] = useState(null);
15
16
async function verifyLogin() {
17
const data = JSON.parse(localStorage.getItem('oauthRedirectData'));
18
localStorage.removeItem('oauthRedirectData');
19
20
try {
21
const { code, state } = myWixClient.auth.parseFromUrl();
22
let tokens = await myWixClient.auth.getMemberTokens(code, state, data);
23
while (!tokens?.refreshToken?.value) {
24
// temporary workaround
25
tokens = await myWixClient.auth.getMemberTokens(code, state, data);
26
}
27
Cookies.set('session', JSON.stringify(tokens));
28
window.location = data?.originalUri || '/';
29
} catch (e) {
30
setNextPage(data?.originalUri || '/');
31
setErrorMessage(e.toString());
32
}
33
}
34
35
useEffect(() => {
36
verifyLogin();
37
}, []);
38
39
return (
40
<article>
41
{errorMessage && (
42
<>
43
<span>{errorMessage}</span>
44
<br />
45
<br />
46
</>
47
)}
48
{nextPage ? <a href={nextPage}>Continue</a> : <>Loading...</>}
49
</article>
50
);
51
}

Middleware

Copy
1
import { createClient, OAuthStrategy } from '@wix/sdk';
2
import { NextResponse } from 'next/server';
3
4
export async function middleware(request) {
5
// generate a session for the visitor if no session exists
6
if (!request.cookies.get('session')) {
7
const response = NextResponse.next();
8
const myWixClient = createClient({
9
auth: OAuthStrategy({ clientId: `10c1663b-2cdf-47c5-a3ef-30c2e8543849` }),
10
});
11
response.cookies.set(
12
'session',
13
JSON.stringify(await myWixClient.auth.generateVisitorTokens())
14
);
15
return response;
16
}
17
}
Was this helpful?
Yes
No