Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/cli/react multitenancy #131

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions boilerplate/frontend/react-multitenancy/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
120 changes: 120 additions & 0 deletions boilerplate/frontend/react-multitenancy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# SuperTokens + React

A demo implementation of [SuperTokens](https://supertokens.com/) with [React](https://react.dev/). Based on [Vite](https://vite.dev/).

## General Info

This project aims to demonstrate how to integrate SuperTokens into a React application. Its primary purpose is to serve as an educational tool, but it can also be used as a starting point for your own project.

## Repo Structure

### Source

```
📦src
┣ 📂assets
┃ ┣ 📂fonts
┃ ┃ ┗ 📜MenloRegular.ttf
┃ ┗ 📂images
┃ ┣ 📜arrow-right-icon.svg
┃ ┣ 📜background.png
┃ ┣ 📜blogs-icon.svg
┃ ┣ 📜celebrate-icon.svg
┃ ┣ 📜guide-icon.svg
┃ ┣ 📜separator-line.svg
┃ ┗ 📜signout-icon.svg
┣ 📂Home --> "Dashboard" component, accessible only via the logged-in state of the app
┃ ┣ 📜CallAPIView.tsx
┃ ┣ 📜Home.css
┃ ┣ 📜SuccessView.tsx
┃ ┗ 📜index.tsx
┣ 📂Auth --> Log in page, customized to allow for choosing tenants
┃ ┣ 📜Auth.css
┃ ┣ 📜TenantSelector.tsx
┃ ┗ 📜index.tsx
┣ 📜App.css
┣ 📜App.tsx --> Root component of the app
┗ 📜main.tsx --> Entry point of the app
```

### Config

#### Vite

Given that the project is a standard Vite project, everything available in the [Vite configuration docs](https://vite.dev/config/) is available to use here (refer to the `vite.config.ts` file). The only customization we've done is changing the port to `3000`.

#### SuperTokens

The full configuration needed for SuperTokens (the frontend part) to work is in the `src/config.tsx` file. This file will differ based on the [auth recipe](https://supertokens.com/docs/guides) you choose.

If you choose to use this as a starting point for your own project, you can further customize the options and config in the `src/config.tsx` file. Refer to our [docs](https://supertokens.com/docs) (and make sure to choose the correct recipe) for more details.

## Application Flow

The application uses [React Router](https://reactrouter.com/) for routing and consists of four main parts:

1. **Entry Point (`main.tsx`)**

- Initializes the React application using `createRoot`
- Renders the main `App` component within React's `StrictMode`

2. **Root Component (`App.tsx`)**

- Initializes SuperTokens with the provided configuration (generated by the CLI)
- Sets up the routing structure using `react-router-dom`
- Wraps the application with necessary providers:
- `SuperTokensWrapper`: Manages auth state and session
- `ComponentWrapper`: Provides auth UI customization for specific auth recipes. For example, if you choose to use the `ThirdPartyPasswordless` recipe, the `ComponentWrapper` will provide the UI customization for the passwordless login flow (showing a disclaimer about the SMS delivery in demo apps).
- Defines three main routes:
- `/`: Public landing page - accessible regardless of auth state
- `/auth`: Renders SuperTokens' pre-built auth UI customized for multi-tenancy - accessible regardless of auth state
- `/dashboard`: Protected route requiring authentication

3. **Home Component (`/` route, `/Home/index.tsx` component)**

- Public landing page accessible to all users
- Provides navigation to authentication and dashboard
- Displays basic application information and links

4. **Auth Component (`/auth` route, `/Auth/index.tsx` component)**

- Public page accessible by all users
- Has customization to allow for choosing tenants
- Different login methods are shown depending on tenant configuration inside of core

5. **Dashboard Component (`/dashboard` route, `/Dashboard/index.tsx` component)**
- Protected route only accessible to authenticated users
- Protected by `SessionAuth` component
- Displays user information and session details
- Provides functionality to:
- View user ID
- Call test API endpoints
- Access documentation
- Sign out

When a user visits the application, they start at the home page (`/`). They can choose to authenticate through the `/auth` route, and once authenticated, they gain access to the protected dashboard. The session state is managed throughout the application using SuperTokens' session management.

## Customizations

If you want to customize the default auth UI, you have two options:

1. Refer to the [docs](https://supertokens.com/docs/thirdpartyemailpassword/advanced-customizations/react-component-override/usage) on how to customize the pre-built UI.
2. Roll your own UI by choosing "Custom UI" in the right sidebar in the [docs](https://supertokens.com/docs/thirdpartyemailpassword/quickstart/frontend-setup).

## Additional resources

- Custom UI Example: https://github.com/supertokens/supertokens-web-js/tree/master/examples/react/with-thirdpartyemailpassword
- Custom UI Blog post: https://supertokens.medium.com/adding-social-login-to-your-website-with-supertokens-custom-ui-only-5fa4d7ab6402
- Awesome SuperTokens: https://github.com/kohasummons/awesome-supertokens

## Contributing

Please refer to the [CONTRIBUTING.md](https://github.com/supertokens/create-supertokens-app/blob/master/CONTRIBUTING.md) file in the root of the [`create-supertokens-app`](https://github.com/supertokens/create-supertokens-app) repo.

## Contact us

For any questions, or support requests, please email us at [email protected], or join our [Discord](https://supertokens.io/discord) server.

## Authors

Created with :heart: by the folks at SuperTokens.io.
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import Session from "supertokens-auth-react/recipe/session";
import Multitenancy from "supertokens-auth-react/recipe/multitenancy";

export function getApiDomain() {
const apiPort = process.env.REACT_APP_API_PORT || 3001;
const apiUrl = process.env.REACT_APP_API_URL || `http://localhost:${apiPort}`;
const apiPort = import.meta.env.VITE_APP_API_PORT || 3001;
const apiUrl = import.meta.env.VITE_APP_API_URL || `http://localhost:${apiPort}`;
return apiUrl;
}

export function getWebsiteDomain() {
const websitePort = process.env.REACT_APP_WEBSITE_PORT || 3000;
const websiteUrl = process.env.REACT_APP_WEBSITE_URL || `http://localhost:${websitePort}`;
const websitePort = import.meta.env.VITE_APP_WEBSITE_PORT || 3000;
const websiteUrl = import.meta.env.VITE_APP_WEBSITE_URL || `http://localhost:${websitePort}`;
return websiteUrl;
}

Expand All @@ -32,15 +32,13 @@ export const SuperTokensConfig = {
websiteDomain: getWebsiteDomain(),
},
usesDynamicLoginMethods: true,
style: styleOverride,
// recipeList contains all the modules that you want to
// use from SuperTokens. See the full list here: https://supertokens.com/docs/guides
style: styleOverride,
recipeList: [
EmailPassword.init(),
ThirdParty.init(),
Passwordless.init({
contactMethod: "EMAIL",
}),
Passwordless.init({ contactMethod: "EMAIL" }),
Session.init(),
Multitenancy.init({
override: {
Expand Down
25 changes: 25 additions & 0 deletions boilerplate/frontend/react-multitenancy/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import js from "@eslint/js";
import globals from "globals";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import tseslint from "typescript-eslint";

export default tseslint.config(
{ ignores: ["dist"] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ["**/*.{ts,tsx}"],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
"react-hooks": reactHooks,
"react-refresh": reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
"react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
},
}
);
15 changes: 15 additions & 0 deletions boilerplate/frontend/react-multitenancy/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/ST.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="//fonts.googleapis.com/css2?family=Rubik:wght@400&display=swap" rel="stylesheet" type="text/css" />
<title>SuperTokens + React</title>
<link rel="manifest" href="/manifest.json" />
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
31 changes: 31 additions & 0 deletions boilerplate/frontend/react-multitenancy/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "react-multitenancy",
"private": true,
"version": "1.0.0",
"type": "module",
"scripts": {
"start": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^7.0.1",
"supertokens-auth-react": "latest"
},
"devDependencies": {
"@eslint/js": "^9.15.0",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.3.4",
"eslint": "^9.15.0",
"eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-react-refresh": "^0.4.14",
"globals": "^15.12.0",
"typescript": "~5.6.2",
"typescript-eslint": "^8.15.0",
"vite": "^6.0.1"
}
}
10 changes: 10 additions & 0 deletions boilerplate/frontend/react-multitenancy/public/React.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions boilerplate/frontend/react-multitenancy/public/ST.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading