Docs

Build a custom flow for creating organizations

Caution

This guide is for users who want to build a custom user interface using the Clerk API. To create organizations using a prebuilt UI, you should use Clerk's prebuilt components.

Organizations are a powerful feature in Clerk that allow you to group users together and manage their permissions. Organizations can be created and managed using the Clerk Dashboard, but you can also allow users within your application to create organizations.

This guide will demonstrate how to use Clerk's API to build a custom flow for creating organizations.

The following example uses the useOrganizationList() hook to get the createOrganization() method. This method is used to create a new organization with the provided name.

This example is written for Next.js App Router but can be adapted for any React meta framework, such as Remix or Gatsby.

app/components/CreateOrganization
'use client';

import { useOrganizationList } from "@clerk/nextjs";
import { FormEventHandler, useState } from "react";

export default function CreateOrganization() {
  const { createOrganization } = useOrganizationList();
  const [organizationName, setOrganizationName] = useState("");

  const handleSubmit: FormEventHandler<HTMLFormElement> = (e) => {
    e.preventDefault();
    createOrganization({ name: organizationName });
    setOrganizationName("");
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        name="organizationName"
        value={organizationName}
        onChange={(e) => setOrganizationName(e.currentTarget.value)}
      />
      <button type="submit">Create organization</button>
    </form>
  );
}

The following example uses the clerk.createOrganization() method to create a new organization with the provided name.

Use the tabs to view the code necessary for the index.html and main.js files.

index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Clerk + JavaScript App</title>
  </head>
  <body>
    <div id="app"></div>

    <h1>Create an organization</h1>
    <form id="create-organization">
      <label for="name">Name</label>
      <input id="name" name="name" />
      <button>Create organization</button>
    </form>

    <script
      type="module"
      src="/src/main.js"
      async
      crossorigin="anonymous"
    ></script>
  </body>
</html>
main.js
import { Clerk } from '@clerk/clerk-js';

const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY;

if (!pubKey) {
  throw new Error('Add your VITE_CLERK_PUBLISHABLE_KEY to .env file');
}

const clerk = new Clerk('YOUR_PUBLISHABLE_KEY');
await clerk.load();

if (clerk.user) {
  const form = document.getElementById('create-organization');

  form.addEventListener('submit', function (e) {
    e.preventDefault();

    const inputEl = document.getElementById('name');

    if (!inputEl) {
      // ... handle empty input
      return;
    }

    clerk.createOrganization({ name: inputEl.value })
      .then((res) => console.log(res))
      .catch((error) => console.log('An error occurred:', error));
  });
} else {
  // If there is no active user, mount Clerk's <SignIn />
  document.getElementById('app').innerHTML = `
    <div id="sign-in"></div>
  `;

  const signInDiv = document.getElementById('sign-in');

  clerk.mountSignIn(signInDiv);
}

Feedback

What did you think of this content?