Pular para o conteúdo

Crie formulários HTML em páginas Astro

No modo SSR, as páginas Astro podem exibir e manipular formulários. Nesta receita, você usará um formulário HTML padrão para enviar dados ao servidor. O seu script frontmatter manipulará os dados no servidor, sem enviar qualquer JavaScript para o cliente.

  • Um projeto com SSR (output: 'server') ativado
  1. Crie ou identifique uma página .astro que irá conter o formulário e seu código de manipulação. Por exemplo, você pode adicionar uma página de registro:

    src/pages/register.astro
    ---
    ---
    <h1>Registrar</h1>
  2. Adicione uma tag <form> com alguns inputs na página. Cada input deve ter um atributo name que descreva o valor daquele campo.

    Certifique-se de incluir um elemento <button> ou <input type="submit"> para enviar o formulário.

    src/pages/register.astro
    ---
    ---
    <h1>Registrar</h1>
    <form>
    <label>
    Nome de usuário:
    <input type="text" name="username" />
    </label>
    <label>
    Email:
    <input type="email" name="email" />
    </label>
    <label>
    Senha:
    <input type="password" name="password" />
    </label>
    <button>Enviar</button>
    </form>
  3. Use atributos de validação para fornecer validação básica no lado do cliente, mesmo que o JavaScript esteja desativado.

    Neste exemplo,

    • required impede o envio do formulário até que o campo seja preenchido.
    • minlength define um comprimento mínimo para o campo.
    • type="email" adiciona validação para aceitar apenas um formato de email válido.
    src/pages/register.astro
    ---
    ---
    <h1>Registrar</h1>
    <form>
    <label>
    Nome de usuário:
    <input type="text" name="username" required />
    </label>
    <label>
    Email:
    <input type="email" name="email" required />
    </label>
    <label>
    Senha:
    <input type="password" name="password" required minlength="6" />
    </label>
    <button>Enviar</button>
    </form>
  4. O envio do formulário fará o navegador solicitar novamente a página. Altere a transferência de dados do formulário method para POST para enviar os dados do formulário como parte do corpo de Request, em vez de como parâmetros na URL.

    src/pages/register.astro
    ---
    ---
    <h1>Registrar</h1>
    <form method="POST">
    <label>
    Nome de usuário:
    <input type="text" name="username" required />
    </label>
    <label>
    Email:
    <input type="email" name="email" required />
    </label>
    <label>
    Senha:
    <input type="password" name="password" required minlength="6" />
    </label>
    <button>Enviar</button>
    </form>
  5. Verifique o método POST no frontmatter e acesse os dados do formulário usando Astro.request.formData(). Envolva isso em um bloco try ... catch para lidar com os casos em que a solicitação POST não foi enviada por um formulário ou quando o formData é inválido.

    src/pages/register.astro
    ---
    if (Astro.request.method === "POST") {
    try {
    const data = await Astro.request.formData();
    const name = data.get("username");
    const email = data.get("email");
    const password = data.get("password");
    // Faça algo com os dados
    } catch (error) {
    if (error instanceof Error) {
    console.error(error.message);
    }
    }
    }
    ---
    <h1>Registrar</h1>
    <form method="POST">
    <label>
    Nome de usuário:
    <input type="text" name="username" required />
    </label>
    <label>
    Email:
    <input type="email" name="email" required />
    </label>
    <label>
    Senha:
    <input type="password" name="password" required minlength="6" />
    </label>
    <button>Enviar</button>
    </form>
  6. Valide os dados do formulário no servidor. Isso deve incluir a mesma validação feita no lado do cliente para evitar envios maliciosos ao seu endpoint e para dar suporte aos raros navegadores legado que não possuem validação de formulário.

    Isso também pode incluir validação que não pode ser feita no lado do cliente. Por exemplo, o exemplo abaixo verifica se o email já está no banco de dados.

    Mensagens de erro podem ser enviadas de volta para o cliente armazenando-as em um objeto errors e acessando-as no template.

    src/pages/register.astro
    ---
    import { isRegistered, registerUser } from "../../data/users"
    import { isValidEmail } from "../../utils/isValidEmail";
    const errors = { username: "", email: "", password: "" };
    if (Astro.request.method === "POST") {
    try {
    const data = await Astro.request.formData();
    const name = data.get("username");
    const email = data.get("email");
    const password = data.get("password");
    if (typeof name !== "string" || name.length < 1) {
    errors.username += "Por favor, insira um nome de usuário. ";
    }
    if (typeof email !== "string" || !isValidEmail(email)) {
    errors.email += "O email não é válido. ";
    } else if (await isRegistered(email)) {
    errors.email += "O email já está registrado. ";
    }
    if (typeof password !== "string" || password.length < 6) {
    errors.password += "A senha deve ter pelo menos 6 caracteres. ";
    }
    const hasErrors = Object.values(errors).some(msg => msg)
    if (!hasErrors) {
    await registerUser({name, email, password});
    return Astro.redirect("/login");
    }
    } catch (error) {
    if (error instanceof Error) {
    console.error(error.message);
    }
    }
    }
    ---
    <h1>Registrar</h1>
    <form method="POST">
    <label>
    Nome de usuário:
    <input type="text" name="username" />
    </label>
    {errors.username && <p>{errors.username}</p>}
    <label>
    Email:
    <input type="email" name="email" required />
    </label>
    {errors.email && <p>{errors.email}</p>}
    <label>
    Senha:
    <input type="password" name="password" required minlength="6" />
    </label>
    {errors.password && <p>{errors.password}</p>}
    <button>Registrar</button>
    </form>
Contribua

O que passa em sua cabeça?

Comunidade