Skip to content

<CreateOrganization />

Create organization form with logo upload, name and slug fields

<CreateOrganization /> is the form for a new organization: name, slug and an optional logo. The new organization becomes the user’s active one. <OrganizationSwitcher /> already shows it in a dialog; render it yourself for a dedicated page, for example in onboarding. It needs organizations: true in src/convex/auth.constants.ts.

Quick start

SvelteKit ships no page for it, so create one:

Next.js ships this page as src/app/organization/create/page.tsx in the organizations/routes item:

src/routes/organization/create/+page.svelte
src/app/organization/create/page.tsx

In SvelteKit, the component reads api from an <AuthProvider> ancestor, which the base src/routes/+layout.svelte provides.

In Next.js, the component needs the ConvexClientProvider from the base layout and a <Suspense> boundary, because it reads redirectTo from the query string with useSearchParams.

What it does

  • Typing a name fills in the slug: lowercased, with spaces turned into hyphens. The user can edit the slug before submitting. If the slug is taken, the server appends -2, -3 and so on until it’s unique.
  • Selecting the logo lets the user pick an image and crop it. The crop is converted to WebP at no more than 512 by 512 pixels, and on submit it’s uploaded to Convex storage through api.storage.generateUploadUrl.
  • Submitting calls the Convex mutation api.organizations.mutations.createOrganization, which creates the organization through Better Auth, adds the user as its owner, and makes it active.
  • While the session loads, the form shows a placeholder. Signed-out visitors see “Authentication Required” instead of the form.

Props

  • onSuccessfulCreate runs after the organization is created, before any redirect. <OrganizationSwitcher /> uses it to close its dialog.
  • redirectTo is where to go after creation. Without it, the component reads the redirectTo query parameter.

Redirects

The target must be a path on your own site. A value that points at another host, or at a //host path, is replaced with /.

Next.js’s /active-organization route sends a user without an active organization to /organization/create?redirectTo=<original path>. The form reads that parameter, so after creation the user returns to the original path through /active-organization, which now resolves to the new organization. See the placeholder for how it resolves.

Without a target, the form resets and stays on the page. That’s the dialog case: the parent closes the dialog in onSuccessfulCreate.