Developers · Users and Permissions
Creating a Sign-Up Form
Last updated 2 November 2026
This document serves as a guide to creating user sign-up forms.
Prerequisites
To follow the steps in this tutorial, you must understand your codebase's required directory structure and the user concept. You are also using the User Profiles created in a previous tutorial.
Steps
Creating a sign-up form is a two-step process:
- Step 1: Create Form Files
- Step 2: Configure Forms
Step 1: Create Form Files
Create a form to sign up developers first. Create a liquid file in the
After creating the form to sign up developers, construct a form for clients by creating a liquid file in the
Step 2: Configure Forms
After creating the two forms, configure them using the article sections below as a guide.
Developer Form
Add the following content to the
---
name: developer_sign_up
resource: User
resource_owner: anyone
redirect_to: /sign-in
fields:
email:
password:
first_name:
validation: { presence: true }
properties:
phone_number:
validation:
phone_number: true
profiles:
developer:
properties:
enabled:
property_options:
default: true
readonly: true
validation:
presence: true
validation:
presence: true
---
{% form %}
<label for='first_name'>First name</label>
<input name='{{ form.fields.first_name.name }}' value='{{ form.fields.first_name.value }}' id='first_name' type='text'>
{% if form.errors.first_name %}
<p>{{ form.errors.first_name }}</p>
{% endif %}
<label for='email'>Email</label>
<input name='{{ form.fields.email.name }}' value='{{ form.fields.email.value }}' id='email' type='email'>
{% if form.errors.email %}
<p>{{ form.errors.email }}</p>
{% endif %}
<label for='password'>Password</label>
<input name='{{ form.fields.password.name }}' id='password' type='password'>
{% if form.errors.password %}
<p>{{ form.errors.password }}</p>
{% endif %}
<label for='first_name'>Phone Number</label>
<input name='{{ form.fields.properties.phone_number.name }}' value='{{ form.fields.properties.phone_number.value }}' id='phone_number' type='text'>
{% if form.errors.properties.phone_number %}
<p>{{ form.errors.properties.phone_number }}</p>
{% endif %}
<input value='{{ form.fields.profiles.developer.properties.enabled.value }}' name='{{ form.fields.profiles.developer.properties.enabled.name }}' type='hidden'>
<button>Create</button>
{% endform %}Notes
: the name of the form, written in snake case. It is used to embed the form on a page. : defines the root resource in this form. In our example, it is . : defines the URL to which the system will redirect the user after success. You can use Liquid. In our example, you will redirect the user to the page. : defines which fields the form accepts; it's possible to define validation of each field. Depending on the , some fields are available without creating . Some of them have pre-defined validation rules due to the backend requirements. In this example, such fields are , with validation that ensures uniqueness (no two users can sign up with the same email address). The email has to be valid and can't be blank. Another field is , which has to be a minimum of six characters long (this is the default validation). : When a user signs up and the password is passed to the password field, Insites stores it as an encrypted password in the database. The encryption uses the bcrypt password hashing function. Besides incorporating a (cryptographic) salt to protect against rainbow table attacks, bcrypt is an adaptive function. Over time, the iteration count can be increased to make it slower, so it remains resistant to brute-force search attacks even with increasing computation power.
Configuration
Configure your form using the properties and settings explained below:
: marked as required. : starts the nested form where you can decide which user defined in are accessible through this form. In this example, you added , explained in the previous tutorial. : this is a special abstraction to easily create the resource associated with the newly signed up . You'll learn about a similar concept later on. Within , you can specify the names of the profiles created in the directory. In our example, you have two choices: and . The is a resource, so you have access to its field. Since you created the sign-up for developer, this is what you used. : a special construction to add special behavior to the field. Here you used , which provides the default value (i.e. the value that will be used if a user does not fill out this field); , on the other hand, ignores the user's input. Because the system will ignore any input by the user, the default value will always be used. This combination is useful if you want to set something in the background and do not want the user to be able to override it.
The configurations and settings described above might need to be clarified first, like what is the
developer:
properties:
enabled:
property_options:
default: true
readonly: true
validation:
presence: truecan also be represented as an independent form with a configuration like this:
...
resource: UserProfile
fields:
properties:
enabled:
property_options:
default: true
readonly: true
...In other words, forms are nested in each other – you can access them as 'nested forms'. In this example, you want to create a
Alternatively, the UI can split the process into two separate actions. It can first ask the user to register, so the button would be labelled 'Sign up'. After registration, the user is then asked if they want to sign up as a developer or a client. In this scenario, the first form would look like this:
---
name: generic_sign_up
resource: User
resource_owner: anyone
redirect_to: /
fields:
email:
password:
first_name:
validation: { presence: true }
---And the second one would be similar to:
---
name: become_developer_form
resource: UserProfile
redirect_to: /
fields:
properties:
enabled:
validation: { presence: true }
property_options:
default: true
readonly: true
---On Insites, you can create multiple resources within one form submission. The result would be the same. The configuration might be more complex, but you can enjoy a highly simplified user experience once that is set up.
Rendering Inputs
The second part of the form is the HTML the system will present to the user on the front end. You will want to include the following in every form.
The most important ones are the CSRF token (called
Another set of hidden inputs is
Optional Inputs
Inputs
Proceeding with rendering proper inputs that the user will be expected to fill:
Write plain HTML inputs, as in the examples on this page. The
Client Form
Add the following content to the
---
name: client_sign_up
resource: User
resource_owner: anyone
redirect_to: /sign-in
fields:
email:
password:
first_name:
validation:
presence: true
profiles:
client:
properties:
enabled:
property_options:
default: true
readonly: true
validation:
presence: true
validation:
presence: true
---
{% form %}
<label for='first_name'>First name</label>
<input name='{{ form.fields.first_name.name }}' value='{{ form.fields.first_name.value }}' id='first_name' type='text'>
{% if form.errors.first_name %}
<p>{{ form.errors.first_name }}</p>
{% endif %}
<label for='email'>Email</label>
<input name='{{ form.fields.email.name }}' value='{{ form.fields.email.value }}' id='email' type='email'>
{% if form.errors.email %}
<p>{{ form.errors.email }}</p>
{% endif %}
<label for='password'>Password</label>
<input name='{{ form.fields.password.name }}' id='password' type='password'>
{% if form.errors.password %}
<p>{{ form.errors.password }}</p>
{% endif %}
<input value='{{ form.fields.profiles.client.properties.enabled.value }}' name='{{ form.fields.profiles.client.properties.enabled.name }}' type='hidden'>
<button>Create</button>
{% endform %}
NextNext Steps
Congratulations! You now know how to create sign-up forms for your users. Now you can embed the sign-up form in a page: Embedding a Sign-Up Form in a Page.