Conclusiones clave
- Configura el formato pdf en /html/convert; los demás formatos producen capturas de pantalla.
- Controla cuándo se toma la instantánea con wait_until y, solo cuando sea necesario, con delay.
- Usa una autenticación limitada a un documento y de corta duración; los headers y los campos siguen siendo visibles en Assembly Status, así que protege el ID de la Assembly y la URL de estado.
La mayoría de los requisitos de un PDF parten de una página que ya se renderiza correctamente en un navegador. Renderizar esa página del lado del servidor suele ser más económico que mantener un segundo diseño en una biblioteca para PDF, siempre que se controlen los tiempos y las entradas.
Lo más importante
- Renderiza desde una URL estable de una plantilla con control de versiones para que un cambio de diseño no pueda alterar un documento ya emitido.
- Combina documentos de varias partes con /document/merge en lugar de concatenar los PDF por tu cuenta.
Renderiza la página que ya tienes
La mayoría de los requisitos de PDF comienzan como una página que ya se renderiza correctamente en un navegador: una factura, un estado de cuenta o un informe. Mantener un segundo diseño en una biblioteca de PDF duplica ese trabajo y hace inevitable que ambos diverjan. /html/convert renderiza la página con un navegador sin interfaz gráfica y devuelve el resultado; establecer format: "pdf" es lo que distingue un documento de una captura de pantalla. El mismo Robot genera jpeg, jpg y png, que son imágenes de la página en lugar de documentos paginados.
El Robot acepta una url para renderizar o un archivo HTML subido. Renderizar una URL suele ser la mejor opción para los documentos que ya existen como páginas, porque mantiene una única fuente de verdad. Subir HTML es adecuado para documentos generados al momento cuando no existe una URL estable.
{
"steps": {
"rendered": {
"robot": "/html/convert",
"url": "https://example.com/inv/1043?v=3",
"format": "pdf",
"wait_until": "networkidle"
},
"exported": {
"use": "rendered",
"robot": "/s3/store",
"credentials": "my_s3_credentials",
"acl": "bucket-default",
"path": "inv/1043/${assembly.id}.pdf"
}
}
}format: "pdf"
Produce el documento. Los demás formatos capturan una imagen de la página.
url o subida
Renderiza una página existente mediante su URL o sube el HTML generado cuando no exista una URL estable.
omit_background
Solo se aplica a la salida de imagen. La transparencia no puede conservarse en un PDF.
Controla cuándo se toma la instantánea
Un documento puede llegar medio vacío cuando un gráfico o una fuente no están listos en el momento de la captura. wait_until selecciona un estado de carga del navegador y su valor predeterminado es networkidle; sus otros valores son domcontentloaded, load y commit. La inactividad de la red no demuestra que los datos de la aplicación, una animación o un gráfico tardío hayan terminado de renderizarse. Seleccionar un estado anterior puede acortar la espera, pero no puede corregir el contenido que sigue faltando con el valor predeterminado.
delay añade una pausa fija después del estado de carga seleccionado. Para el contenido que se renderiza tarde, primero haz que la página se renderice a partir de datos ya disponibles siempre que sea posible; luego prueba un retraso acotado cuando la página no pueda indicar su disponibilidad mediante su comportamiento de carga. Esa pausa aumenta la latencia en cada renderizado, incluidos los que no la necesitaban. Verifica el PDF real en lugar de tratar la inactividad de la red o una espera fija como garantía de que el contenido esté completo.
wait_until
Por defecto es networkidle. Un estado de carga del navegador no garantiza que el contenido de la aplicación esté listo.
delay
Añade una pausa fija después del estado de carga seleccionado en cada renderizado. Pruébala con contenido que termina de cargarse más tarde.
Hoja de estilos de impresión
Verifica la página en la vista previa de impresión de un navegador antes de renderizarla del lado del servidor.
Accede a páginas protegidas sin exponer credenciales
Como el renderizado ejecuta un navegador real, Transloadit debe poder acceder a la página. Los documentos suelen estar protegidos mediante autenticación, lo que deja dos opciones viables. El parámetro headers pasa la autenticación con la solicitud, una opción adecuada para el acceso basado en tokens. Como alternativa, emite una URL firmada de corta duración que conceda acceso exactamente a un documento durante un periodo breve.
Usa un token de corta duración, preferiblemente de uso único, limitado a un solo documento. Quien tenga el ID de la Assembly o la URL de estado puede recuperar Assembly Status sin más autenticación, incluidos sus campos. El ejemplo pasa el token mediante fields.token, por lo que es visible ahí. notification_payload: ["without_params"] elimina params, template y merged_params de las notificaciones; no elimina campos ni oculta datos del estado. Nunca uses aquí un token reutilizable de la cuenta. Mantén los IDs, las URL de estado y las respuestas de estado sin procesar fuera de los registros públicos y de las respuestas al cliente, oculta los tokens en los registros de la aplicación y haz que el acceso al documento caduque con independencia de la retención del estado.
{
"notification_payload": ["without_params"],
"steps": {
"rendered": {
"robot": "/html/convert",
"url": "https://example.com/reports/q3",
"format": "pdf",
"wait_until": "networkidle",
"headers": {
"Authorization": "Bearer ${fields.token}"
}
}
}
}headers
Transporta fuera de la URL un token de corta duración limitado al documento. Trata como información sensible los parámetros de la Assembly y los registros.
URL firmadas de un solo uso
Concede acceso a un solo documento durante un periodo breve cuando la autenticación mediante encabezados no está disponible.
No usar nunca la cadena de consulta
Las credenciales incluidas allí quedan registradas dondequiera que se almacene la URL renderizada.
Haz que el documento reemitido sea idéntico al original
Una factura es un registro legal, y la versión que un cliente recibe en marzo debe seguir renderizándose de forma idéntica en noviembre. Dos prácticas permiten conseguirlo. Renderiza desde la URL de una plantilla con control de versiones para que un cambio de diseño posterior no pueda alterar un documento ya emitido, y almacena el archivo resultante en lugar de volver a generarlo bajo demanda.
Conviene gestionar explícitamente los documentos formados por varias partes. Usa /document/merge con los alias document_1, document_2 y los siguientes alias as para establecer el orden, y habilita bundle_steps: true para reunir las partes. Así evitas depender de los nombres de los archivos de entrada o dar a un segundo servicio acceso a las partes.
{
"steps": {
"cover": {
"robot": "/html/convert",
"url": "https://example.com/stmt/cover?v=3",
"format": "pdf",
"wait_until": "networkidle"
},
"detail": {
"robot": "/html/convert",
"url": "https://example.com/stmt/detail?v=3",
"format": "pdf",
"wait_until": "networkidle"
},
"statement": {
"use": {
"steps": [
{ "name": "cover", "as": "document_1" },
{ "name": "detail", "as": "document_2" }
],
"bundle_steps": true
},
"robot": "/document/merge"
}
}
}Versionar la plantilla
Un cambio de diseño debe producir documentos nuevos, no modificar retroactivamente los ya emitidos.
Almacenar, no volver a generar
Conserva el archivo producido para que una reemisión sea una copia y no un nuevo renderizado.
/document/merge
Combina documentos de varias partes en una sola Assembly; usa alias as explícitos para controlar el orden.
Mantén predecible el costo de renderizar
Renderizar una página es más costoso que convertir un formato porque implica iniciar un navegador, obtener subrecursos y esperar a que la página se estabilice. Ese costo es aceptable para un documento solicitado por un cliente, pero es un desperdicio cuando el mismo estado de cuenta vuelve a renderizarse cada vez que alguien abre una vista de lista. La solución habitual consiste en renderizarlo una sola vez cuando el documento pasa a ser definitivo y luego servir el archivo almacenado.
La generación masiva requiere un tratamiento separado. Una ejecución de fin de mes que produzca miles de estados de cuenta no debe competir con el renderizado que espera un cliente, y un delay fijo aplicado a todo el lote se multiplica hasta representar tiempo y dinero considerables. Medir el costo por documento emitido, en lugar de por Assembly, suele revelar rápidamente estos patrones.
Renderizar al finalizar
Produce el archivo cuando el documento pase a ser definitivo, no cada vez que se visualice.
Separar las ejecuciones masivas
Mantén los lotes de fin de mes separados de los renderizados que una persona está esperando.
Auditar los retrasos fijos
Una pausa de un segundo es imperceptible una vez, pero costosa al aplicarla a diez mil documentos.
Verifica el documento antes de que lo vea un cliente
Un renderizado puede completarse correctamente y aun así ser incorrecto. El Robot devuelve un PDF válido independientemente de que el gráfico se haya dibujado o no, por lo que una comprobación que solo verifique si se produjo un archivo no detectará una página en blanco. Algunas verificaciones sencillas permiten detectar la mayoría de estos problemas: un tamaño en bytes plausible, la cantidad esperada de páginas y la presencia de una cadena conocida, como el número del documento.
Durante el desarrollo, renderizar en png junto con el PDF permite hacer una comprobación visual rápida y fácil de evaluar a simple vista durante la revisión. Además, comparar un nuevo renderizado con una imagen de referencia almacenada permite detectar regresiones de diseño que una comprobación del tamaño en bytes no puede identificar. Ninguna de estas prácticas corresponde a la ruta de producción, pero conviene incluir ambas en el pipeline que publica los cambios de las plantillas.
Verificar el contenido, no la existencia
Comprueba la cantidad de páginas y un identificador conocido, no solo que exista un archivo.
Renderizar imágenes para revisión
Un png de la misma página permite revisar de un vistazo los cambios de la plantilla.
Comparar con una referencia
La comparación visual detecta regresiones de diseño que las comprobaciones de tamaño no identificarán.
Detalles técnicos que conviene conocer
- El parámetro format acepta jpeg, jpg, pdf y png. Solo pdf produce un documento; los demás capturan una imagen de la página.
- El parámetro omit_background se aplica a la salida de imagen y no tiene efecto cuando format es pdf, por lo que la transparencia no puede conservarse en el documento.
- El parámetro wait_until tiene como valor predeterminado networkidle y selecciona un estado de carga del navegador. No garantiza que los gráficos, las fuentes o los datos de la aplicación tardíos estén listos.
- El parámetro delay añade una pausa fija después de alcanzar el estado de carga. Prueba un retraso acotado para el contenido que se renderiza tarde y ten en cuenta la latencia añadida en cada renderizado.
- Una factura renderizada es un registro legal. Renderizarla desde la URL inmutable de una plantilla y almacenar el archivo resultante, en lugar de volver a generarlo bajo demanda, mantiene una copia reemitida idéntica al original.
- Como el renderizado ejecuta un navegador real, Transloadit debe poder acceder a la página. Las páginas protegidas por una cookie de sesión necesitan una URL firmada de un solo uso o que las credenciales se transmitan mediante el parámetro headers.
Un enfoque práctico
- 1
Crea el documento como una página normal con una hoja de estilos de impresión y verifícalo primero en un navegador.
- 2
Renderízalo con /html/convert mediante el formato pdf y un wait_until explícito.
- 3
Almacena el resultado en un bucket privado junto con los identificadores que lo generaron. Usa bucket-default para buckets de S3 con las ACL deshabilitadas y aplica el control de acceso mediante la política del bucket.
- 4
Combina las páginas complementarias en un solo archivo con /document/merge cuando el documento tenga varias partes.
Cuándo resulta útil Transloadit
Usa /html/convert con el formato pdf cuando el documento ya exista como página web o pueda renderizarse como tal. Indica una url, o sube el HTML y deja que el Robot renderice el archivo subido. Combínalo con /document/merge cuando varias páginas deban formar un solo archivo.
Límite de la arquitectura
/html/convert renderiza una página con un navegador sin interfaz gráfica, por lo que produce una copia visual paginada en lugar de un PDF etiquetado y accesible. Los documentos que necesiten una estructura seleccionable, campos de formulario o formatos de archivo a largo plazo como PDF/A deben generarse con un generador de documentos específico.
Preguntas frecuentes
¿Por qué faltan gráficos o fuentes en mi PDF?
Es posible que la página no haya terminado de renderizar el contenido de su aplicación. El valor predeterminado de wait_until ya es networkidle, que no garantiza que los gráficos o las fuentes tardíos estén listos. Renderiza desde datos ya disponibles siempre que sea posible, o prueba un retraso acotado después del estado de carga. Inspecciona el PDF para confirmar que aparece el contenido que faltaba; la pausa fija aumenta la latencia en cada renderizado.
¿Puedo generar un PDF con fondo transparente?
No. omit_background afecta la salida de imagen y no tiene efecto cuando format es pdf. Si necesitas transparencia, renderiza a png y coloca esa imagen en un documento.
¿Cómo renderizo una página que requiere iniciar sesión?
Pasa la autenticación mediante el parámetro headers o emite una URL firmada de corta duración cuyo alcance se limite a un solo documento. Evita incluir credenciales en la cadena de consulta, porque la URL renderizada queda registrada dondequiera que se registre el renderizado.
¿El resultado es un PDF accesible y etiquetado?
No. Un navegador sin interfaz gráfica produce una copia visual paginada, no un documento etiquetado con un orden de lectura, campos de formulario o conformidad con PDF/A. Ese tipo de requisitos necesita un generador de documentos específico, no el renderizado de una página.
¿Cómo combino varias páginas renderizadas en un solo archivo?
Renderiza cada parte y pasa los resultados a /document/merge dentro de la misma Assembly. Asigna los alias document_1, document_2 y los siguientes alias as, y habilita bundle_steps: true. Sin alias explícitos, el Robot ordena por nombre de archivo, no por el orden de los nombres de los Steps en el array.