Skip to main content
Docs

Build a custom flow for creating organizations

Warning

This guide is for users who want to build a custom user interface using the Clerk API. To use a prebuilt UI, use the Account Portal pages or prebuilt components.

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

The following example uses the useOrganizationList() hook to access 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-based framework.

app/components/CreateOrganization.tsx
'use client'  import { useOrganizationList } from '@clerk/nextjs' import { FormEventHandler, useState } from 'react'  export default function CreateOrganization() {  const { isLoaded, createOrganization } = useOrganizationList()  const [organizationName, setOrganizationName] = useState('')   if (!isLoaded) return null   const handleSubmit: FormEventHandler<HTMLFormElement> = async (e) => {  e.preventDefault()  createOrganization({ name: organizationName })  .then((res) => {  console.log(res)  })  .catch((err) => {  // See https://clerk.com/docs/guides/development/custom-flows/error-handling  // for more info on error handling  console.error(JSON.stringify(err, null, 2))  })  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 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(pubKey) await clerk.load()  if (clerk.isSignedIn) {  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

Last updated on