How to set a Daily Prebuilt username programmatically before joining a call

At Daily, we try to solve the problems in video calls that many of us commonly experience. For example, if you’ve ever been in a large call before, especially one with a chat widget, it can be frustrating to try to follow the conversation if call participants haven’t set their name.

Daily Prebuilt chat with everyone’s name set to the default value — “Guest”

Because we know the value of seeing others’ names in calls, we do our best to encourage call participants to set their names before joining a Daily Prebuilt call with our name form. And by “encourage”, we mean a name form automatically shows before you can join the call in many cases. (More on that below.)

Daily Prebuilt's prejoin UI name form

Occasionally, there are times when this form can be less than ideal. One specific case is if you are embedding Daily Prebuilt in your app and you’re using your own external form to get the participant’s name.

Daily TalkJs demo app with its own name form

This exact situation happened in one of our own demo apps recently, in fact. Our Daily Prebuilt and TalkJs chat integration app uses a form prior to loading the Daily <iframe> (i.e. video call) because the name also needs to be passed to TalkJs’s ChatBox widget.

The issue this created, however, was that the participant would fill out the form, go to join the call, and then be faced with the Daily Prebuilt name form. 😬

Filling out the chat integration demo's form only to get the same name field in the Daily Prebuilt UI

Two forms in a row with the exact same prompt? As developers, we’ll try to turn any bug into a feature — no? Just me? 😇 — but we can all admit this is not great UX.

When your engineering team codes faster than you can hit Publish 🏃‍♀️

In today’s tutorial, we’ll look at two ways to set your participants’ usernames using a name they have already provided before joining a Daily Prebuilt call, whether it be from a web form or authenticated account.

  1. Meeting tokens: Originally, the only solution relied on using a Daily meeting token. This works well, but means you need to create meeting tokens for your participants before they can join, so there’s one extra Daily API request to make. (Technically, you can also use self-signed meeting tokens, but we won’t get into that here.) That said, you may be using meeting tokens anyway, so they're still a good option.

  2. Daily methods: In between writing the demo code and getting this tutorial published, our ⚡lightning⚡ fast front-end team at Daily (hi, Christian 👋) made this process even easier. Daily's createFrame and join methods can now also be used to set the local username before joining.

To cover our bases, we’ll discuss both solutions today.


Understanding when the Daily Prebuilt name form shows

You may be wondering when you need to consider if the name form will show if you’re using Daily Prebuilt.

To answer this, we’ll need to consider our room configuration settings. Let’s take a closer look at how room settings impact the UI that shows in your Daily Prebuilt calls.

How the enable_prejoin_ui room setting affects the join flow

Daily Prebuilt prejoin UI with the local camera and microphone turned off

Daily Prebuilt offers a handy “prejoin” UI where a participant can test their devices and see their camera feed before technically joining the call. The name form is part of the prejoin UI setup, which means the enable_prejoin_ui room setting controls both the prejoin UI view and the name form.

If enable_prejoin_ui is set to false, the participant immediately joins the call when they visit the room URL. If a username isn’t set in the browser’s local storage, which is handled internally by Daily Prebuilt, their username will be set to “Guest”. Otherwise, it will be set to what’s in local storage.

Daily Prebuilt using the name in local storage when prejoin UI is disabled

However, if enable_prejoin_ui is set to true, when the participant goes to join the call, they will first see the prejoin UI.

There are two possibilities for what is shown first in the prejoin UI:

  1. If a username has previously been set in the browser’s local storage, that name will be used and the participant will see their device options and video.
Daily Prebuilt prejoin UI with the more menu displayed and local video muted
  1. If the username is not set in local storage, the name form will show, which requires a name to be entered. Submitting this form will bring the user to the prejoin UI just like option one above.
Name form showing in Daily Prebuilt as part of the prejoin user flow

To be clear, this second possibility is what we’re trying to avoid today. 😓 If we already have a user’s name in our app, we don’t want to ask them to fill out this name form again.


Skipping Daily Prebuilt’s name form with a Daily meeting token

As mentioned, we have a couple options for setting the participant username to bypass the Daily Prebuilt name form.

Let’s start with the more involved option: using a Daily meeting token. We’ll use the Daily Prebuilt and TalkJs demo app for the sample code below.

Daily+TalkJs demo join form
const submitJoinForm = async (e) => {
   e.preventDefault();
   const roomUrl = roomRef?.current?.value;
   const name = usernameRef?.current?.value;
 
   // Get the room name from the URL
   // https://DOMAIN.daily.co/ROOM_NAME
   const roomName = roomUrl.split("/").at(-1);
   // create a token for the room with the username provided
   const res = await api.createDailyToken(roomName, name);
   if (res.token) {
     setToken(res.token);
     setLocalUsername(name);
     setRoom(roomUrl);
   } else {
     // Show error
   }
 };
JoinForm.jsx

When the app’s “join form” is submitted with the method submitJoinForm, two pieces of information are retrieved from it:

  • The Daily room URL
  • The participant’s name

In submitJoinForm, we get the room name from the URL provided (e.g. https://DOMAIN.daily.co/ROOM_NAME) by taking the value after the last /.

Once we have the room name, we can then create a new Daily meeting token.

createDailyToken: async (roomName, username) => {
   const tokenReq = await fetch(`https://api.daily.co/v1/meeting-tokens`, {
     method: "POST",
     headers: {
       Accept: "application/json",
       "Content-Type": "application/json",
       Authorization: "Bearer " + process.env.REACT_APP_DAILY_API_KEY,
     },
     body: JSON.stringify({
       properties: { room_name: roomName, user_name: username },
     }),
   });
   const res = await tokenReq.json();
   return res;
 },
api.js

To make the token specific to that user, we pass the room name and username supplied by the join form in the endpoint's request body. If the request is successful, a token will be returned, which will be passed to the Call component as a prop.

const createAndJoinCall = useCallback(() => {
   const newCallFrame = DailyIframe.createFrame(
     callRef?.current,
     CALL_OPTIONS
   );
 
   newCallFrame.join({ url: room, token });
 
   ...
   setCallFrame(newCallFrame);
 }, [room, setCallFrame, localUsername, token]);
Call.jsx

From Call, we can initialize the DailyIframe instance in the component method createAndJoinCall with the Daily method createFrame. The call can then be joined, passing the room URL and the token we just created as DailyIframe configuration properties.

The result of this is being able to use the prejoin UI without ever seeing Daily Prebuilt’s name form. The username gets pulled right from the token.💥

Filling out the app's name form and skipping Daily Prebuilt's name form

To see another example of how to do this, check out our Daily and Twilio Flex WebChat chat integration demo app. In this example, a Daily room and token are created, and the DailyIframe is created and joined all in one concise method.


Skipping the name form with the createFrame or join Daily methods

The second and more straightforward way to set the username is to supply a userName value in the call properties at one of two points in the call joining process:

  1. When the DailyIframe is created with createFrame
  2. When the call is programmatically joined with the join method

Let’s update our TalkJs demo code in the createAndJoinCall method to see how this would look.

Using createFrame to set the username

We’ll start by updating our joinCall method in the JoinForm component:

 const joinCall = async (e) => {
   e.preventDefault();
   const roomUrl = roomRef?.current?.value;
   const name = usernameRef?.current?.value;
 
   // Get the room name from the URL
   // https://DOMAIN.daily.co/ROOM_NAME
   const roomName = roomUrl.split("/").at(-1);
 
   setLocalUsername(name);
   setRoom(roomUrl);
 };
JoinForm.jsx

This is the same code as above but with the token creation removed.

Next we’ll update our Call component, specifically in the createAndJoinCall method:

const createAndJoinCall = useCallback(() => {
   const newCallFrame = DailyIframe.createFrame(callRef?.current, {
     ...CALL_OPTIONS,
     userName: localUsername,
   });
 
   newCallFrame.join({ url: room });
   ...
Call.jsx

We now pass our localUsername provided by JoinForm in the createFrame call options (the second parameter). In join, we only have to pass the room URL and no token.

These changes will produce the exact same effect as the meeting token had to bypass the name form and preset the username.

One more option: Using the join instance method

The join method gives us another opportunity to set a username programmatically.

Similar to the createFrame example above, we can skip creating a token and update the createAndJoinCall method like so:

const createAndJoinCall = useCallback(() => {
   const newCallFrame = 
      DailyIframe.createFrame(callRef?.current, CALL_OPTIONS);
 
   newCallFrame.join({
      url: room,
      userName: localUsername,
   });
   ...
Call.jsx

Here, we pass our userName value in the join method options instead of createFrame and get the exact same effect of bypassing the name form.


What if I do all of the above at the same time?

Even though we wouldn’t recommend using all of these solutions together, it’s good to understand which ones have the highest priority when used together.

If you pass a username to createFrame, join, and set it in a token, the token’s username will be used.

If you pass a username to createFrame and join, but don’t set it in a token, the username from join will be used. This is because join happens after createFrame, so it will update the username settings again.

You may also decide you want to update a username after joining the call, in which case you can use the Daily method setUserName.

Wrapping up

With Daily Prebuilt, we’ve done most of the heavy lifting for you to set up your video calls but we still provide several options for you to customize the video call experience, like described above. To learn more about Daily Prebuilt, check out our docs. 💅

And, as always, if you’ve ever not sure how to do something with Daily’s APIs, let us know! We’re happy to help!

Never miss a story

Get the latest direct to your inbox.