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.
Pré-requisitos
Seção intitulada Pré-requisitos- Um projeto com SSR (EN) (
output: 'server'
) ativado
Receita
Seção intitulada Receita-
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> -
Adicione uma tag
<form>
com alguns inputs na página. Cada input deve ter um atributoname
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> -
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>Você pode adicionar lógica de validação personalizada que refere-se a vários campos usando a tag
<script>
e a Constraint Validation API.Para escrever lógica de validação complexa mais facilmente, você pode construir seu formulário usando um framework frontend e escolher uma biblioteca de formulários como React Hook Form ou Felte.
-
O envio do formulário fará o navegador solicitar novamente a página. Altere a transferência de dados do formulário
method
paraPOST
para enviar os dados do formulário como parte do corpo deRequest
, 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> -
Verifique o método
POST
no frontmatter e acesse os dados do formulário usandoAstro.request.formData()
. Envolva isso em um blocotry ... catch
para lidar com os casos em que a solicitaçãoPOST
não foi enviada por um formulário ou quando oformData
é 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> -
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>