Skip to content
  • SDKs and APIs
  • Back end SDKs

Remix SDK

This SDK is for developers using Remix.

New to Kinde? Get started here.

Create a back end application in Kinde

Link to this section

The Remix SDK works with back end applications. Create one in Kinde. See Add and manage applications.

Install the Kinde Remix SDK into your Remix project

Link to this section
Terminal window
npm i @kinde-oss/kinde-remix-sdk

Set callback URLs

Link to this section
  1. In Kinde, go to Settings > Applications > [Your app] > View details.
  2. Add your callback URLs in the relevant fields. For example:
    • Allowed callback URLs (also known as redirect URIs) - for example http://localhost:3000/kinde-auth/callback
    • Allowed logout redirect URLs - for example http://localhost:3000
  3. Select Save.

Set up environment variables

Link to this section

While you are in your Kinde backend application, copy the Client ID and Client secret, redirect URLs, etc. Add these details to the Environment variables for your application.

.env

Terminal window
KINDE_CLIENT_ID=<your-client-id>
KINDE_CLIENT_SECRET=<your-client-secret>
KINDE_ISSUER_URL=https://<your-kinde-subdomain>.kinde.com
KINDE_SITE_URL=http://localhost:3000
KINDE_POST_LOGOUT_REDIRECT_URL=http://localhost:3000
KINDE_POST_LOGIN_REDIRECT_URL=http://localhost:3000

Set up authentication routes

Link to this section

Create this file app/routes/kinde-auth.$index.tsx.

import { handleAuth } from "@kinde-oss/kinde-remix-sdk";
import { LoaderFunctionArgs } from "@remix-run/node";
export async function loader({ params, request }: LoaderFunctionArgs) {
return await handleAuth(request, params.index);
}

Authentication

Link to this section

Sign up and sign in

Link to this section

Authenticate users by redirecting them to /kinde-auth/login and /kinde-auth/register with the Remix <Link /> component.

import { Link } from "@remix-run/react";
<Link to={"/kinde-auth/login"}>
Login
</Link>
<Link to={"/kinde-auth/register"}>
Register
</Link>

Sign into organizations

To log into specific organizations you can specify the org_code in the search params.

<Link
to={{
pathname: "/kinde-auth/login",
search: "?org_code=org_af90783xxxx",
}}
>
Sign in
</Link>

Internationalization

You can set the language you wish your users to see when they hit the login flow by including lang in the search params.

<Link
to={{
pathname: "/kinde-auth/login",
search: "?lang=fr",
}}
>
Sign in
</Link>

This is implemented in much the same way as signing up or signing in. Use the remix <Link /> component to redirect users to /kinde-auth/logout.

import {Link} from "@remix-run/react";
<Link to={"/kinde-auth/logout"}>Logout</Link>;

Protect routes

Link to this section

In the loader, check if the user exists and then handle route protection there.

In this example we will redirect the user to sign in if there is no login data.

export const loader = async ({request}: LoaderFunctionArgs) => {
const {getUser, headers} = await getKindeSession(request);
const user = await getUser();
if (user === null) {
throw redirect("/kinde-auth/login");
}
return json({user}, {headers});
};

Return to a specific page after authentication

Link to this section

After a user has logged in following a redirect from a protected route, we usually want to send the user back to the page they were trying to access prior to logging in.

This can be achieved with the returnTo search parameter added to the login/register url.

export const loader = async ({request}: LoaderFunctionArgs) => {
const {getUser, headers} = await getKindeSession(request);
const user = await getUser();
if (user === null) {
throw redirect("/kinde-auth/login?returnTo=/protected-route");
}
return json({user}, {headers});
};

Call a function after authentication

Link to this section

After a user has authenticated, you may want to call a function to update your database or perform some other action.

This can be achieved by passing onRedirectCallback to the handleAuth function.

import {handleAuth} from "@kinde-oss/kinde-remix-sdk";
import {LoaderFunctionArgs} from "@remix-run/node";
export async function loader({params, request}: LoaderFunctionArgs) {
return await handleAuth(request, params.index, {
onRedirectCallback({user}) {
console.log("This is called after the user is authenticated!", user);
}
});
}

Kinde session data - getKindeSession()

Link to this section
const {
getUser,
getBooleanFlag,
getFlag,
getIntegerFlag,
getStringFlag,
getPermission,
getClaim,
getClaimValue,
getOrganization,
getPermissions,
getToken,
getUserOrganizations,
getUserProfile,
isAuthenticated
} = await getKindeSession(request);

getClaim(claim, type): Fetches a specific claim from the user’s session based on the provided claim name and type. Returns an object with name and value properties, or null on error.

getClaimValue(claim, type): Similar to getClaim, but retrieves only the claim’s value. Returns the value or null on error.

Authentication and user information

Link to this section

getToken(): Retrieves the current access token from the session. Returns the token or null when the user is not authenticated or on error.

refreshTokens(): Attempts to refresh the user’s access and refresh tokens. Returns true on success or throws an error.

isAuthenticated(): Checks if a valid session exists, indicating a logged-in user. Returns true if authenticated, otherwise false.

getUser(): Retrieves the user information associated with the current session. Returns a user object or null on error or if the user is not authenticated.

getUserProfile(): Fetches the user’s profile details from Kinde. Returns a user profile object or null on error or if the user is not authenticated.

getFlag(code, defaultValue, type): Retrieves a feature flag value by code. Optionally provides a default value and type for parsing the retrieved value. Returns the flag value or the default value on error.

getBooleanFlag(code, defaultValue): Retrieves a boolean feature flag.

getIntegerFlag(code, defaultValue): Retrieves an integer feature flag.

getStringFlag(code, defaultValue): Retrieves a string feature flag.

getPermission(permission): Checks if a specific permission is granted to the user. Returns true if granted, false otherwise.

getPermissions(): Retrieves all permissions associated with the user’s session. Returns an array of permission strings or an empty array on error.

getOrganization(): Fetches information about the user’s current organization. Returns an organization object or null on error.

getUserOrganizations(): Retrieves a list of organizations the user belongs to. Returns an array of organization objects or an empty array on error.

Using refresh tokens

Link to this section

Refresh tokens used to keep the user session alive. You can pass through the headers from getKindeSession through to the loader fetch response. Or you can use the refreshTokens function to refresh the user’s access and refresh tokens manually.

// Refresh tokens in the background
export const loader = async ({request}: LoaderFunctionArgs) => {
const {headers} = await getKindeSession(request);
return json({paylod: "Refreshing tokens in the backgrounf"}, {headers});
};
// Refresh tokens manually
export const action = ({request}: ActionFunctionArgs) => {
const {refreshTokens} = await getKindeSession(request);
const headers = refreshTokens();
return redirect("/profile", {headers});
};

Get up-to-date Kinde data

Link to this section

To get up-to-date Kinde data into your app you can use the refreshTokens function in an action function and then include the headers in the response.

export const action = ({request}: ActionFunctionArgs) => {
const {refreshTokens} = await getKindeSession(request);
const headers = refreshTokens();
return redirect('/profile', {headers});
}

Kinde Management API

Link to this section

To use our management API please see @kinde/management-api-js