# Eleventy

> Un shortcode de Eleventy que renderiza un formulario de Ikiform en plantillas Nunjucks, Liquid y Markdown, con el id del formulario en los datos globales.

Eleventy genera HTML estático, así que el formulario se envía sin JavaScript en el cliente. Un shortcode mantiene el markup en un solo lugar y funciona igual en archivos Nunjucks, Liquid y Markdown.

## Configúralo

### Paso 1: Añade el shortcode

`eleventy.config.js`:

```js
const escape = (value) => String(value).replace(/[&<>"']/g, (char) => `&#${char.charCodeAt(0)};`);

export default function (eleventyConfig) {
  eleventyConfig.addShortcode("ikiform", (formId, thanks = "", subject = "") =>
    [
      `<form class="ikiform" action="https://ikiform.com/f/${encodeURIComponent(formId)}" method="post">`,
      '<label>Email <input name="email" type="email" autocomplete="email" required></label>',
      '<label>Message <textarea name="message" rows="5"></textarea></label>',
      thanks && `<input type="hidden" name="_redirect" value="${escape(thanks)}">`,
      subject && `<input type="hidden" name="_subject" value="${escape(subject)}">`,
      '<input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden>',
      '<button type="submit">Send</button>',
      "</form>",
    ]
      .filter(Boolean)
      .join("\n"),
  );
}
```

- Las líneas se unen sin líneas en blanco a propósito. En Markdown, una línea en blanco termina un bloque HTML, y el resto del formulario se trataría como texto.
- Usa la sintaxis de módulos ES. Si tu `package.json` no tiene `"type": "module"`, llama al archivo `eleventy.config.mjs`.

### Paso 2: Guarda el id del formulario en los datos globales

`_data/ikiform.js`:

```js
export default {
  formId: process.env.IKIFORM_FORM_ID ?? "frm_xxxxxxxxxxxxxxxx",
  thanks: "https://example.com/thanks/",
};
```

Los datos globales están disponibles en todas las plantillas como `ikiform`. La URL de agradecimiento debe ser absoluta y `https:`, porque Ikiform ignora las demás redirecciones.

### Paso 3: Úsalo

`contact.md`:

```text
---
title: Contact
---

Questions about pricing? Write to us.

{% ikiform ikiform.formId, ikiform.thanks, "Pricing question" %}
```

Los archivos Markdown se procesan con Liquid por defecto, así que la etiqueta funciona tal como está escrita. Déjala en su propia línea y no la sangres con cuatro espacios, o Markdown la mostrará como un bloque de código. La misma etiqueta funciona en archivos `.njk` y `.liquid`.

`_redirect` solo se sigue cuando el formulario tiene dominios permitidos que incluyen tu sitio. Consulta [Reglas de _redirect](https://ikiform.com/es/docs/html.md#redirect-rules).

## Dominios permitidos

Incluye producción y cada host de vista previa. Los sitios de Eleventy suelen desplegarse en Netlify o Cloudflare Pages, que gestionan las vistas previas de forma distinta.

| Dónde funciona el formulario | Añadir a Allowed domains |
| --- | --- |
| `npx @11ty/eleventy --serve` | `localhost`. Coincide con `http://localhost:8080`: Ikiform solo compara el nombre de host, nunca el puerto. |
| Tu dominio | `example.com`, que también cubre `www.example.com` |
| Netlify | `your-site.netlify.app`. Los deploy previews (`deploy-preview-12--your-site.netlify.app`) y los branch deploys (`branch--your-site.netlify.app`) no son subdominios suyos, así que añade el host exacto de la vista previa mientras la pruebas. |
| Cloudflare Pages | `your-project.pages.dev`. Las URL de vista previa como `abc123.your-project.pages.dev` son subdominios suyos, así que ya coinciden. |

- Nunca añadas `netlify.app` ni `pages.dev` solos. Coincidiría cualquier sitio de ese host, incluidos los de otras personas.

## Lista de pruebas

1. Ejecuta el servidor de desarrollo y mira el código fuente de la página. El formulario debería ser HTML normal, no estar dentro de un bloque `<pre><code>`.
2. Envía en local con `localhost` en los dominios permitidos y confirma que el envío aparece en Ikiform.
3. Despliega una vista previa y vuelve a enviar desde el host de la vista previa.
4. Envía en producción y confirma que llegas a tu página de agradecimiento.

## Solución de problemas

| Qué ves | Por qué | Solución |
| --- | --- | --- |
| El formulario aparece como código en la página | El shortcode está sangrado con cuatro espacios en un archivo Markdown | Mueve la etiqueta al principio de su línea. |
| La mitad del formulario se renderiza como párrafos | La salida del shortcode contiene una línea en blanco, que termina el bloque HTML de Markdown | Une las líneas sin líneas en blanco, como en la configuración de arriba. |
| `SyntaxError: Unexpected token 'export'` al arrancar Eleventy | La configuración usa sintaxis de módulos ES en un proyecto CommonJS | Cámbiale el nombre a `eleventy.config.mjs`, o añade `"type": "module"` a `package.json`. |
| Nunjucks o Liquid no encuentran la etiqueta `ikiform` | Eleventy no cargó el archivo de configuración | Comprueba que el archivo está en la raíz del proyecto y se llama `eleventy.config.js` o `.mjs`. |
| Los envíos llegan al filtro de spam con `origin_mismatch` | La página que envió no está entre los dominios permitidos del formulario | Añade el host de la tabla de arriba. Si eliges **Reject**, esos mismos envíos reciben `403 origin_not_allowed`. |

## Relacionado

- [Hugo](https://ikiform.com/es/docs/guides/hugo.md): Un partial y un shortcode para los archivos de contenido.
- [Jekyll](https://ikiform.com/es/docs/guides/jekyll.md): Un include y la configuración de GitHub Pages.
- [Formularios HTML](https://ikiform.com/es/docs/html.md): Redirecciones, campos reservados y el honeypot.
- [Dominios permitidos](https://ikiform.com/es/docs/spam.md#allowed-domains): Cómo se comparan los orígenes y qué pasa cuando no coinciden.
