Customize deep link team URL
It'd be awesome if there was a way to customize the deep link team URL
Instead of:
/teams/4762ce00-13e3-4be5-9b40-bc35fcaedcb1
This:
/teams/acme
@fomalhautb I would like to put together a PR for this if you are okay with it.
Users could pick between the existing /uuid ("/teams/c058811c-b4d3-4fd4-960f-a9a6a61752b5") method or a custom /team-slug ("/teams/acme") method.
Proposal for the /team-slug method
Backend modifications
Modify the Team model:
model Team {
// ...
slug String? @unique
}
Valid slugs are lowercase, start with an alphanumeric character, are followed by dashes or more alphanumeric characters, and end with an alphanumeric character.
Slugs could be set while creating a team:
const team = await user.createTeam({
displayName: 'Stack-Auth Inc.',
slug: 'stack'
});
or, set by updating the team:
await team.update({
slug: 'stack-auth'
});
Crucially, these must updates must be atomic & unique - so createTeam(..)/updateTeam(..) should throw an error if another team already exists with a given slug. I believe this will be handled by Postgres automatically.
Usage
Usage would be similar to your deep link example:
"use client";
import { useUser, SelectedTeamSwitcher } from "@stackframe/stack";
export default function TeamPage({ params }: { params: { teamSlug: string } }) {
const user = useUser({ or: 'redirect' });
const team = user.useTeamBySlug(params.teamSlug);
if (!team) {
return <div>Team not found</div>;
}
return (
<div>
<SelectedTeamSwitcher
urlMap={team => `/team/${team.slug}`}
selectedTeam={team}
/>
<p>Team Name: {team.displayName}</p>
<p>You are a member of this team.</p>
</div>
);
}
Other notes
Resolving a team slug to a team id shouldn't require authentication.
For example, I'm building a CRM that allows teams to publish events, like /my-company/my-event/sign-up, where my-company is the team slug. This event sign up is publicly accessible - so visitors won't have a user account - this means that user.useTeamBySlug wouldn't work. We probably need an API for this, something like:
const app = useStackApp();
// User does not have to be on the team, or be signed in at all. Notice that ONLY the teamId should be returned.
string teamId = app.useTeamBySlug('my-company');
// User must be signed in & on the team
const team = user.useTeamBySlug(params.teamSlug);
Then, we leave it up to the programmer to decide whether to restrict the page how they see fit.