api.denorly.com
Ir al sitio →
Trata sobre: Formularios

Axios en frameworks JS

Next.js, Gatsby, Astro… da igual. Es un POST HTTPS a /f/{TOKEN}. Axios solo lo hace más corto.

Install + la llamada

npm i axios
const res = await axios.post(
  "https://denorly.com/f/TOKEN",
  data, // objeto plano: { nombre, email, mensaje }
  { headers: { "Content-Type": "application/json", "Accept": "application/json" } }
);
res.data.success; // true

El {TOKEN} no es secreto: va en el cliente sin problema, es la auth por diseño. Igual no hace falta una API key. Si proxeas desde el servidor (más abajo) es para ocultarlo de la vista o meter lógica (rate-limit, honeypot, logging), no por seguridad de credenciales.

Por framework

Opción A: Client Component (postea directo)

"use client";
import { useState } from "react";
import axios from "axios";

const TOKEN = "8f3b2c1a-9d4e-4f7a-b6c2-1e5a7d9c0b3f";

export default function ContactForm() {
  const [sent, setSent] = useState(false);
  const [error, setError] = useState("");

  async function onSubmit(e) {
    e.preventDefault();
    setError("");
    const data = Object.fromEntries(new FormData(e.currentTarget));
    try {
      const res = await axios.post(`https://denorly.com/f/${TOKEN}`, data, {
        headers: { "Content-Type": "application/json", "Accept": "application/json" },
      });
      if (res.data.success) setSent(true);
    } catch (err) {
      // Denorly devuelve el motivo en err.response.data.error
      setError(err.response?.data?.error ?? "Error de red");
    }
  }

  if (sent) return <p>¡Enviado!</p>;
  return (
    <form onSubmit={onSubmit}>
      <input name="nombre" required />
      <input name="email" type="email" required />
      <textarea name="mensaje" />
      {error && <p style={{ color: "red" }}>{error}</p>}
      <button type="submit">Enviar</button>
    </form>
  );
}

Opción B: Route Handler proxy (App Router)

El cliente postea a /api/contact y el server reenvía. El TOKEN vive en una env var, no en el bundle.

// app/api/contact/route.js
import axios from "axios";

export async function POST(req) {
  const data = await req.json();
  try {
    const res = await axios.post(
      `https://denorly.com/f/${process.env.DENORLY_TOKEN}`,
      data,
      { headers: { "Content-Type": "application/json", "Accept": "application/json" } }
    );
    return Response.json(res.data, { status: 200 });
  } catch (err) {
    const body = err.response?.data ?? { success: false, error: "upstream error" };
    return Response.json(body, { status: err.response?.status ?? 502 });
  }
}

O como Server Action: misma idea, marca el módulo con "use server" y haz el axios.post dentro de la action: el TOKEN nunca toca el cliente.

⚠ Gotchas

  • Axios lanza en respuestas no-2xx. Lee el motivo en err.response.data.error (no en err.message). Status: 402 límite, 403 origen/recaptcha, 404 form inactivo, 400 validación.
  • CORS desde el navegador funciona: el endpoint envía cabeceras CORS. Pero si configuraste una allow-list de dominios en el form y tu origen no está, recibes 403 ORIGIN_BLOCKED. En planes free cualquier origen pasa.
  • No hay objeto de errores por campo. error es un único string, no esperes errors.email.