Skip to main content

Guide: Integrate TideCloak SDK in a React Application

This guide will help you integrate TideCloak SDK to manage user authentication in a React application. Follow the steps below to set up and customize the example provided.

Prerequisites

Before you begin, ensure that you have:

  • A TideCloak instance running locally or on a server.
  • A realm and a client configured in TideCloak.
  • Basic knowledge of React and JavaScript.
  • Node.js and npm installed on your machine.

Set Up Tidecloak and Tide IDP

Before starting the integration, make sure you have both Tidecloak and the TIDE Identity Provider (IDP) set up and running. This is crucial for managing user authentication in your application. You can refer to the following setup guides:

  • How to Set Up Tidecloak – In this guide, you will configure Tidecloak with the same values used in this tutorial (e.g., localhost:8000 for the app).
  • How to Set Up the TIDE IDP – This guide helps you configure the TIDE Identity Provider, which will serve as your authentication server.

By following these setup guides, you'll ensure your environment is ready to integrate with your app using the values provided in this tutorial. Please continue with the steps below to integrate Tide Using React.

Set Up the Development Environment

1. Set Up the Project

Create a new React project or use an existing one. If you're starting fresh, you can create a new React app with the following command:

npx create-react-app my-tidecloak-app
cd my-tidecloak-app

Make sure your files App.js, index.js, and styles.css inside the src/ folder contain the following code:

src/App.js

import React from "react";
import "./styles.css";
import Keycloak from "keycloak-js";

export default function App() {
var keycloak = new Keycloak({
url: "http://localhost:8080",
realm: "myrealm",
clientId: "myclient"
});

keycloak
.init({
checkLoginIframe: false
})
.then(function (authenticated) {
alert(authenticated ? keycloak.token : "not authenticated");
})
.catch(function (ex) {
console.log(ex);
alert("failed to initialize");
});

const loginUrl = keycloak.createLoginUrl({
scope: "openid",
redirectUri: "http://localhost:8000",
locale: "en",
checkLoginIframe: false
});

const registerUrl = keycloak.createRegisterUrl({
scope: "openid email",
redirectUri: "http://localhost:8000",
locale: "en",
action: "register",
prompt: "login",
checkLoginIframe: false
});

console.log('registerUrl', registerUrl);
console.log('loginUrl', loginUrl);

const handleRegisterClick = () => {
keycloak
.register({
scope: "openid",
redirectUri: "http://localhost:8000",
locale: "en",
action: "register",
prompt: "login",
checkLoginIframe: false
})
.then((result) => {
console.log("result", result);
});
};

return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<a href={loginUrl} rel="noreferrer" target="_blank">
loginUrl
</a>
<h2>Start editing to see some magic happen!</h2>
<a href={registerUrl} rel="noreferrer" target="_blank">
registerUrl
</a>
<h2>Start editing to see some magic happen!</h2>
<button onClick={handleRegisterClick}>registerButton</button>
</div>
);
}

src/index.js

import React from "react";
import { createRoot } from "react-dom/client";
import App from "./App";

const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(<App />);

src/styles.css

.App {
font-family: sans-serif;
text-align: center;
}

Ensure that your public/index.html file matches the following content. This is the default template provided by Create React App, which serves as the entry point for your React application.

public/index.html

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.

Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>

<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.

You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.

To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>

</html>

Your project folder structure should look like this now:

my-keycloak-app/

├── public/
│ └── index.html

├── src/
│ ├── App.js
│ ├── index.js
│ └── styles.css

├── node_modules/

├── package.json
├── package-lock.json
└── README.md

2. Install TideCloak JS Adapter

Install the TideCloak JavaScript adapter using npm:

npm install keycloak-js

3. Initialize TideCloak

In the App.js file, initialize TideCloak with your realm and client configuration:

var keycloak = new Keycloak({
url: "http://localhost:8080",
realm: "myrealm",
clientId: "myclient"
});

If you are following along with our sample project, your values will be the same as those provided in this guide.

4. Implement the Login and Registration Functions

In the App.js file, use the following code to create login and registration URLs, and handle the login and registration processes:

const loginUrl = keycloak.createLoginUrl({
scope: "openid",
redirectUri: "http://localhost:8000",
locale: "en",
checkLoginIframe: false
});

const registerUrl = keycloak.createRegisterUrl({
scope: "openid email",
redirectUri: "http://localhost:8000",
locale: "en",
action: "register",
prompt: "login",
checkLoginIframe: false
});

const handleRegisterClick = () => {
keycloak
.register({
scope: "openid",
redirectUri: "http://localhost:8000",
locale: "en",
action: "register",
prompt: "login",
checkLoginIframe: false
})
.then((result) => {
console.log("result", result);
});
};

5. Display User Information

In the App.js file, once authenticated, you can access and display the user information or token as needed. In this example, an alert will show the token if the user is authenticated:

keycloak
.init({
checkLoginIframe: false
})
.then(function (authenticated) {
alert(authenticated ? keycloak.token : "not authenticated");
})
.catch(function (ex) {
console.log(ex);
alert("failed to initialize");
});

6. Run the Application

Now, you can run your React application. Start your development server using the following command:

npm start

Open your browser and navigate to http://localhost:8000 (or the port specified by your setup). You should see your React application with links to log in and register.

7. Finish and Test

By following the steps above, you should now have a fully functional TideCloak login integration in your React application. Open your browser, navigate to http://localhost:8000, and test the login and registration processes.

8. Try It Out: Full Example Code

To try out the TideCloak integration without going through each step, you can copy the complete code for App.js, index.js, styles.css, and index.html, and then run your React app as described in Step 6.

Your project folder structure should look like this:

my-keycloak-app/

├── public/
│ └── index.html

├── src/
│ ├── App.js
│ ├── index.js
│ └── styles.css

├── node_modules/

├── package.json
├── package-lock.json
└── README.md

public/index.html

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.

Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>

<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.

You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.

To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>

</html>

src/App.js

import React from "react";
import "./styles.css";
import Keycloak from "keycloak-js";

export default function App() {
var keycloak = new Keycloak({
url: "http://localhost:8080",
realm: "myrealm",
clientId: "myclient"
});

keycloak
.init({
checkLoginIframe: false
})
.then(function (authenticated) {
alert(authenticated ? keycloak.token : "not authenticated");
})
.catch(function (ex) {
console.log(ex);
alert("failed to initialize");
});

const loginUrl = keycloak.createLoginUrl({
scope: "openid",
redirectUri: "http://localhost:8000",
locale: "en",
checkLoginIframe: false
});

const registerUrl = keycloak.createRegisterUrl({
scope: "openid email",
redirectUri: "http://localhost:8000",
locale: "en",
action: "register",
prompt: "login",
checkLoginIframe: false
});

console.log('registerUrl', registerUrl);
console.log('loginUrl', loginUrl);

const handleRegisterClick = () => {
keycloak
.register({
scope: "openid",
redirectUri: "http://localhost:8000",
locale: "en",
action: "register",
prompt: "login",
checkLoginIframe: false
})
.then((result) => {
console.log("result", result);
});
};

return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<a href={loginUrl} rel="noreferrer" target="_blank">
loginUrl
</a>
<h2>Start editing to see some magic happen!</h2>
<a href={registerUrl} rel="noreferrer" target="_blank">
registerUrl
</a>
<h2>Start editing to see some magic happen!</h2>
<button onClick={handleRegisterClick}>registerButton</button>
</div>
);
}

src/index.js

import React from "react";
import { createRoot } from "react-dom/client";
import App from "./App";

const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(<App />);

src/styles.css

.App {
font-family: sans-serif;
text-align: center;
}