diff --git a/webapp/src/Form/User/SignupFormType.php b/webapp/src/Form/User/SignupFormType.php
new file mode 100644
index 0000000000000000000000000000000000000000..624f376f86d47408453518fccf4b277f22259dbc
--- /dev/null
+++ b/webapp/src/Form/User/SignupFormType.php
@@ -0,0 +1,130 @@
+<?php
+
+/*
+ * This file is part of the Comptoir-du-Libre software.
+ * <https://gitlab.adullact.net/Comptoir/comptoir-du-libre>
+ *
+ * Copyright (c) ADULLACT   <https://adullact.org>
+ *               Association des Développeurs et Utilisateurs de Logiciels Libres
+ *               pour les Administrations et les Collectivités Territoriales
+ *
+ * Comptoir-du-Libre is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this software. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>.
+ */
+
+declare(strict_types=1);
+
+namespace App\Form\User;
+
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\Extension\Core\Type\EmailType;
+use Symfony\Component\Form\Extension\Core\Type\PasswordType;
+use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+use Symfony\Component\Translation\TranslatableMessage;
+use Symfony\Component\Validator\Constraints\Length;
+use Symfony\Component\Validator\Constraints\NotBlank;
+use Symfony\Component\Validator\Constraints\Email;
+
+class SignupFormType extends AbstractType
+{
+    public const HONEYPOT_FIELD_NAME = 'email';
+    public const EMAIL_FIELD_NAME = 'login';
+
+    public function buildForm(FormBuilderInterface $builder, array $options): void
+    {
+
+        $builder
+            ->add(self::HONEYPOT_FIELD_NAME, EmailType::class, [
+                'label' => 'signup.form.label.email',
+                'required'   => false,
+                'label_attr' => [
+                    'tabindex' => "-1",
+                    'aria-hidden' => "true",
+                    'class' => 'visually-hidden'
+                ],
+                'attr' => [
+                    'tabindex' => "-1",
+                    'aria-hidden' => "true",
+                    'type' => 'email',
+                    'class' => 'visually-hidden'
+                ],
+            ])
+            ->add(self::EMAIL_FIELD_NAME, EmailType::class, [
+
+                'label' => 'signup.form.label.email',
+                'help' => 'signup.form.label.email.help',
+                'constraints' => [
+                    new NotBlank([
+                        'message' => 'common.validator.help.field.error.required',
+                    ]),
+                    new Email([
+                        'mode' => 'html5',
+                        'message' => 'common.validator.help.email.error.not-valid',
+                    ]),
+                ],
+            ])
+            ->add('plainPassword', RepeatedType::class, [
+                'type' => PasswordType::class,
+                'options' => [
+                    'attr' => [
+                        'autocomplete' => 'new-password',
+                        'minlength' => $options['min_password_length'],
+                        'maxlength' => 4096, // max length allowed by Symfony for security reasons
+                    ],
+                ],
+                'first_options' => [
+                    'constraints' => [
+                        new NotBlank([
+                            'message' => 'common.validator.help.field.error.required',
+                        ]),
+                        new Length([
+                            'min' => $options['min_password_length'],
+//                          'minMessage' => 'Password should be at least {{ limit }} characters',
+                            'minMessage' => new TranslatableMessage(
+                                message: 'common.validator.help.password.error.too-short',
+                            ),
+                            'max' => 4096, // max length allowed by Symfony for security reasons
+                        ]),
+                    ],
+                    'label' => 'signup.form.label.password',
+                    'help_html' => true,
+                    'help' => new TranslatableMessage(
+                        message: 'signup.form.label.password.help',
+                        parameters: ['{ min_password_length }' => $options['min_password_length']],
+                        domain: 'messages'
+                    ),
+                ],
+                'second_options' => [
+                    'label' => 'signup.form.label.password-repeat',
+                    'help' => 'signup.form.label.password-repeat.help',
+                ],
+                'invalid_message' => 'common.validator.help.password.error.password-must-match',
+                // Instead of being set onto the object directly,
+                // this is read and encoded in the controller
+                'mapped' => false,
+            ])
+        ;
+    }
+
+    public function configureOptions(OptionsResolver $resolver): void
+    {
+        $resolver->setDefaults([
+            'min_password_length' => 16,
+            // enable/disable CSRF protection for this form
+            'csrf_protection' => true,
+            // the name of the hidden HTML field that stores the token
+            'csrf_field_name' => 'csrf_token_Signup',
+            // an arbitrary string used to generate the value of the token
+            // using a different string for each form improves its security
+            'csrf_token_id'   => 'task_SignupFormType',
+        ]);
+        $resolver->setAllowedTypes('min_password_length', 'int');
+    }
+}
diff --git a/webapp/templates/app_base_header.html.twig b/webapp/templates/app_base_header.html.twig
index 48e17137bd68560a110d0160a99d62be470252b0..a4aab1ceeed6a4654f51f589407fdc6a3dbcbf19 100644
--- a/webapp/templates/app_base_header.html.twig
+++ b/webapp/templates/app_base_header.html.twig
@@ -40,7 +40,9 @@
                 </li>
             {% else %}
                 <li class="d-flex align-items-start mb-1">
-                    {{ 'public.link.signup'|trans }}
+                    <a href="{{ path('app_account_signup_init') }}">
+                        {{ 'public.link.signup'|trans }}
+                    </a>
                 </li>
                 <li class="d-flex align-items-start mb-1">
                     <a href="{{ path('app_account_login') }}">
diff --git a/webapp/templates/user/signup.html.twig b/webapp/templates/user/signup.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..06b1168ca37c67d55987928f7656e1cf143ef059
--- /dev/null
+++ b/webapp/templates/user/signup.html.twig
@@ -0,0 +1,46 @@
+{% extends 'app_base.html.twig' %}
+{% form_theme signupForm 'bootstrap_5_layout.html.twig' %}
+
+{% block title %} {{ 'signup.head.title'|trans }} - {{ app_name }}{% endblock %}
+{% block body %}
+    <nav aria-label="breadcrumb">
+        <ol class="breadcrumb">
+            <li class="breadcrumb-item">
+                <a href="{{ path('app_home_i18n') }}">{{ 'breadcrumb.homepage'|trans }}</a>
+            </li>
+            <li class="breadcrumb-item active">
+                <a href="{{ path('app_account_signup_init') }}"
+                   aria-current="page">{{ 'breadcrumb.user.signup'|trans }}</a>
+            </li>
+        </ol>
+    </nav>
+
+    <h1>
+        {{ 'signup.page.title'|trans }}
+    </h1>
+    <div  class="col-md-8">
+{#      {{ form_start(signupForm) }}    #}
+{#      {{ form_start(signupForm, {'attr': {'novalidate': 'novalidate'}}) }}    #}
+        {{ form_start(signupForm) }}
+            {{ form_row(signupForm.email)  }}
+            <fieldset class="mt-4 mb-4 ">
+                <legend class="text-xl text-bg-dark px-2">
+                    {{ 'signup.form.fieldset.user.title'|trans }}
+                </legend>
+                {{ form_row(signupForm.login)  }}
+            </fieldset>
+
+            <fieldset class="mt-4 mb-4 ">
+                <legend class="text-xl text-bg-dark px-2">
+                    {{ 'signup.form.fieldset.password.title'|trans }}
+                </legend>
+                {{ form_row(signupForm.plainPassword)  }}
+            </fieldset>
+
+            <button id="public_signupForm_submit" class="btn btn-primary">
+                {{ 'signup.form.submit'|trans|raw }}
+            </button>
+        {{ form_end(signupForm) }}
+    </div>
+
+{% endblock %}
diff --git a/webapp/translations/messages+intl-icu.en.yaml b/webapp/translations/messages+intl-icu.en.yaml
index 4e9a2ee61596b1c9499cc04438a5d1977616f282..0861241f9e3a0b6c64b38c81bca641dbaee5e107 100644
--- a/webapp/translations/messages+intl-icu.en.yaml
+++ b/webapp/translations/messages+intl-icu.en.yaml
@@ -28,6 +28,7 @@ user.link.profile: 'Profile'
 ##################################################################################################################
 breadcrumb.homepage: 'Home'
 breadcrumb.user.login: 'Sign in'
+breadcrumb.user.signup: 'Sign up'
 breadcrumb.user.lost_password.form: 'Reset your password'
 ##################################################################################################################
 breadcrumb.user.account: 'Account setting'
@@ -68,6 +69,22 @@ login.form.label.account: 'Email'
 login.form.label.password: 'Password'
 login.form.submit: '<strong>Sign in</strong> to your account'
 ##################################################################################################################
+signup.head.title: 'Create an account'
+signup.page.title: 'Create your account'
+signup.form.submit: '<strong>Create</strong> your account'
+signup.form.fieldset.user.title: 'User account'
+signup.form.label.email: 'Email address'
+signup.form.label.email.help: 'Enter your email address, and we will send you a link to activate your account.'
+signup.form.fieldset.password.title: 'Password'
+signup.form.label.password: 'Your password'
+signup.form.label.password.help: |
+    Please enter your password.
+    It should be at least <strong>{ min_password_length }</strong> characters.
+signup.form.label.password-repeat: 'Repeat password'
+signup.form.label.password-repeat.help: 'Please repeat your password.'
+signup.success: 'Your account has been successfully created.'
+signup.error.account_already_exists: 'User account already exists'
+##################################################################################################################
 forgot_password.request.head.title: 'Forgot your password?'
 forgot_password.request.page.title: 'Forgot your password?'
 forgot_password.request.form.submit: 'Send password reset email'
diff --git a/webapp/translations/messages+intl-icu.fr.yaml b/webapp/translations/messages+intl-icu.fr.yaml
index a0762a4c112883911f2cee6ec1371415139d616d..bb36f9662da97307990d65d7b9009756411b8013 100644
--- a/webapp/translations/messages+intl-icu.fr.yaml
+++ b/webapp/translations/messages+intl-icu.fr.yaml
@@ -29,6 +29,7 @@ user.link.profile: 'Profil'
 ##################################################################################################################
 breadcrumb.homepage: 'Accueil'
 breadcrumb.user.login: 'Se connecter'
+breadcrumb.user.signup: 'Créer un compte'
 breadcrumb.user.lost_password.form: 'Réinitialiser votre mot de passe'
 ##################################################################################################################
 breadcrumb.user.account: 'Paramètres'
@@ -69,6 +70,23 @@ login.form.label.account: 'Adresse email'
 login.form.label.password: 'Mot de passe'
 login.form.submit: '<strong>Se connecter</strong> à votre compte'
 ##################################################################################################################
+signup.head.title: 'Créer un compte'
+signup.page.title: 'Créer un compte'
+signup.form.submit: '<strong>Créer</strong> votre compte'
+signup.form.fieldset.user.title: 'Votre compte utilisateur'
+signup.form.label.email: 'Adresse email'
+signup.form.label.email.help: 'Saisir votre adresse email et nous vous enverrons un lien pour activer votre compte.'
+signup.form.fieldset.password.title: 'Votre mot de passe'
+signup.form.label.password: 'Mot de passe'
+signup.form.label.password.help: |
+    Veuillez saisir votre mot de passe.
+    Il doit comporter au moins <strong>{ min_password_length }</strong> caractères.
+signup.form.label.password-repeat: 'Répéter le mot de passe'
+signup.form.label.password-repeat.help: 'Veuillez de nouveau saisir votre mot de passe'
+signup.success: 'Votre compte a été créé avec succès.'
+signup.error.account_already_exists: "Un compte utilisateur existe déjà pour cette adresse mail."
+                                         # Un utilisateur ayant ce courriel existe déjà.
+##################################################################################################################
 forgot_password.request.head.title: 'Mot de passe oublié ?'
 forgot_password.request.page.title: 'Mot de passe oublié ?'
 forgot_password.request.form.submit: 'Réinitialiser votre <strong>mot</strong> de <strong>passe</strong>'
diff --git a/webapp/translations/validators+intl-icu.en.yaml b/webapp/translations/validators+intl-icu.en.yaml
index 0bf477eeb4e87e988ede3a68e20c93a2f7c74b3e..6d2720ee5274d9747cad44d9c41ad2dbcbb0ce83 100644
--- a/webapp/translations/validators+intl-icu.en.yaml
+++ b/webapp/translations/validators+intl-icu.en.yaml
@@ -1,3 +1,4 @@
+common.validator.help.password.error.password-must-match: 'The password fields must match.'
 common.validator.help.password.error.new-password-must-match: 'The new password fields must match.'
 common.validator.help.email.error.not-valid: 'Please enter a valid email address.'
 common.validator.help.password.error.too-short: 'Password size is too small.'
diff --git a/webapp/translations/validators+intl-icu.fr.yaml b/webapp/translations/validators+intl-icu.fr.yaml
index db1ad1f50fa0a2877e27bf50441fa77f58858924..041ec03e54f7fb240416dfcc239a6856173d64bc 100644
--- a/webapp/translations/validators+intl-icu.fr.yaml
+++ b/webapp/translations/validators+intl-icu.fr.yaml
@@ -1,3 +1,4 @@
+common.validator.help.password.error.password-must-match: 'Les champs du mot de passe doivent correspondre.'
 common.validator.help.password.error.new-password-must-match: 'Les champs du nouveau mot de passe doivent correspondre.'
 common.validator.help.email.error.not-valid: 'Veuillez saisir une adresse email valide.'
 common.validator.help.password.error.too-short: 'La taille du mot de passe est trop petite.'