Docs

Adding satellite domains

Clerk supports sharing sessions across different domains by adding one or many satellite domains to an application.

Your "primary" domain is where the authentication state lives, and satellite domains are able to securely read that state from the primary domain, enabling a seamless authentication flow across domains.

Users must complete the sign-in flow on the primary domain, either using Clerk’s <SignIn /> component or useSignIn() hook.

To access authentication state from a satellite domain, users will be transparently redirected to the primary domain. If users need to sign in, they must be redirected to a sign in flow hosted on the primary domain, then redirected back to the originating satellite domain.

How to add satellite domains

Warning

Currently, multi-domain can be added to any Next.js or Remix application. For other React frameworks, multi-domain is still supported as long as you do not use server rendering or hydration.

To get started, you need to create an application from the Clerk Dashboard. Once you create an instance via the Clerk Dashboard, you will be prompted to choose a domain. This is your primary domain. For the purposes of this guide, the primary domain will be primary.dev.

When building your sign-in flow, you must configure it to run within your primary application, e.g. on /sign-in.

Note

For more information about creating your application, check out Clerk's detailed guide.

Add your first satellite domain

In the Clerk Dashboard, go to the Domains page and then open the Satellite tab. Click on the Add satellite domain button to add a new satellite domain of your choice. Then, follow the instructions provided.

For the purposes of this guide, the satellite domain will be "satellite.dev".

The 'Satellite' tab on the Domains page in the Clerk Dashboard.

Configure your satellite app

There are two ways that you can configure your Clerk satellite application to work with the primary domain:

  • Using environment variables
  • Using properties

Configure your satellite app with environment variables

You can configure your satellite application by setting the following environment variables:

.env.local
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=YOUR_PUBLISHABLE_KEY
CLERK_SECRET_KEY=YOUR_SECRET_KEY

NEXT_PUBLIC_CLERK_DOMAIN=satellite.dev
NEXT_PUBLIC_CLERK_IS_SATELLITE=true

NEXT_PUBLIC_CLERK_SIGN_IN_URL=https://primary.dev/sign-in
.env
CLERK_PUBLISHABLE_KEY=YOUR_PUBLISHABLE_KEY
CLERK_SECRET_KEY=YOUR_SECRET_KEY

CLERK_SIGN_IN_URL=https://primary.dev/sign-in
CLERK_DOMAIN=satellite.dev
CLERK_IS_SATELLITE=true

Configure your satellite app with properties

You can configure your satellite application as a satellite application by setting the isSatellite, domain, and signInUrl properties.

The properties related to the multi-domain setup are:

  • Name
    isSatellite
    Type
    boolean or (url: URL) => boolean
    Description

    This option defines that the application is a satellite application.

  • Name
    domain
    Type
    string or (url: URL) => boolean
    Description

    This option sets the domain of the satellite application. This is required since we cannot figure this out by your publishable key, since it is the same for all of your multi-domain apps.

  • Name
    signInUrl
    Type
    string
    Description

    This url will be used for any redirects that might happen and needs to point to your primary application. This option is optional for production instances and required for development instances.

The URL parameter that can be passed to isSatellite and domain is the request url for server side usage or the current location for client usage.

In a Next.js application, you must set the properties in the <ClerkProvider> component and in your authMiddleware().

Configuring your <ClerkProvider> component should look like this:

_app.tsx
import { ClerkProvider } from "@clerk/nextjs";
import Head from "next/head";

export default function App({ Component, pageProps }) {
  return (
    <ClerkProvider isSatellite domain={(url) => url.host} signInUrl='https://primary.dev/sign-in' {...pageProps}>
      <Head>
        <title>Satellite Next.js app</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      </Head>
      <Component {...pageProps} />
    </ClerkProvider>
  );
}

And your middleware should look like this:

middleware.ts
import {
  clerkMiddleware,
  createRouteMatcher
} from "@clerk/nextjs/server"

// Set the homepage as a public route
const isPublicRoute = createRouteMatcher(["/"])

// Set the necessary options for a satellite application
const options = {
  isSatellite: true,
  signInUrl: 'https://primary.dev/sign-in',
  domain: 'https://primary.dev',
};

export default clerkMiddleware((auth, req) => {
  if (isPublicRoute(req)) return; // if it's a public route, do nothing
  auth().protect(); // for any other route, require auth
}, options);

export const config = {
  matcher: ["/((?!.+\\.[\\w]+$|_next).*)", "/", "/(api|trpc)(.*)"],
}

In a Remix application, you must set the properties in the ClerkApp wrapper.

root.tsx
export const loader = (args) => {
  return rootAuthLoader(
    args,
    ({ request }) => {
      const { userId, sessionId, getToken } = request.auth;
      return json({
          message: `Hello from the root loader :)`,
          ENV: getBrowserEnvironment(),
      });
    },
    {
      loadUser: true,
      signInUrl: 'https://primary.dev/sign-in',
      isSatellite: true,
      domain: (url) => url.host
    } as const
  );
};

export default ClerkApp(App, {
  isSatellite: true,
  domain: (url) => url.host,
  signInUrl: 'https://primary.dev/sign-in',
});

Ready to go 🎉

Your satellite application should now be able to access the authentication state from your satellite domain!

You can see it in action by:

  1. Visiting the primary domain and signing in.
  2. Visiting the satellite domain.
  3. You now have an active session in the satellite domain, so you can see the <UserProfile /> component and update your information.

You can repeat this process and create as many satellite applications as you need.

You can also check out the example repository with a primary and a satellite Next.js application.

If you have any questions about satellite domains, or you're having any trouble setting this up, please contact support@clerk.com

Feedback

What did you think of this content?