Principais pontos
- Defina o formato pdf em /html/convert; os outros formatos geram capturas de tela.
- Controle quando o instantâneo é capturado com wait_until e, somente quando necessário, com delay.
- Envie a autenticação por cabeçalhos em vez de incorporar credenciais na URL.
A maioria dos requisitos de PDF começa como uma página que já é renderizada corretamente em um navegador. Renderizar essa página no servidor costuma sair mais barato do que manter um segundo layout em uma biblioteca de PDF, desde que o momento da captura e as entradas sejam controlados.
O que mais importa
- Renderize a partir de uma URL de modelo estável e versionada, para que uma mudança de design não altere um documento já emitido.
- Mescle documentos com várias partes usando /document/merge em vez de concatenar PDFs por conta própria.
Renderize a página que você já tem
A maioria dos requisitos de PDF começa como uma página que já é renderizada corretamente em um navegador: uma fatura, um extrato, um relatório. Manter um segundo layout em uma biblioteca de PDF duplica esse trabalho e garante que os dois vão divergir. O Robot /html/convert renderiza a página com um navegador headless e retorna o resultado, e é a definição de format: "pdf" que distingue um documento de uma captura de tela. O mesmo Robot produz jpeg, jpg e png, que são imagens da página, e não documentos paginados.
O Robot aceita tanto uma url para renderizar quanto um arquivo HTML enviado por upload. Renderizar uma URL costuma ser a melhor escolha para documentos que já existem como páginas, porque mantém uma única fonte da verdade. Enviar HTML por upload é mais adequado para documentos montados na hora, quando não existe uma URL estável.
{
"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.pdf"
}
}
}format: "pdf"
Produz o documento. Os outros formatos capturam uma imagem da página.
url ou upload
Renderize uma página existente pela URL ou envie por upload o HTML gerado quando não houver uma URL estável.
omit_background
Aplica-se apenas à saída de imagem. A transparência não pode ser levada para um PDF.
Controle quando o instantâneo é capturado
A falha mais comum é um documento que é renderizado corretamente quando você abre a página manualmente, mas chega do Robot meio vazio, porque o instantâneo foi capturado antes de as fontes carregarem ou de um gráfico terminar de ser desenhado. wait_until corresponde ao estado de carregamento do navegador e é a forma precisa de expressar essa dependência. Escolher o estado de carregamento certo resolve a maioria dos problemas de tempo sem adicionar latência fixa.
delay adiciona uma pausa fixa depois disso. Às vezes, ela é necessária para animações ou widgets de terceiros que informam que estão prontos antes de realmente estarem, mas tem o custo dessa pausa em todas as renderizações, inclusive nas que não precisavam dela. Recorra primeiro a um valor mais específico de wait_until e trate delay como alternativa de reserva, e não como padrão.
wait_until
Expressa a dependência real do estado de carregamento do navegador. Dê preferência a ele.
delay
Uma pausa fixa cobrada em cada renderização. Use apenas quando um estado de carregamento não conseguir expressar a espera.
Folha de estilo de impressão
Verifique a página na visualização de impressão do navegador antes de renderizá-la no lado do servidor.
Acesse páginas protegidas sem vazar credenciais
Como a renderização executa um navegador real, a página precisa estar acessível a partir da Transloadit. Os documentos geralmente ficam protegidos por autenticação, o que deixa duas opções viáveis. O parâmetro headers envia a autenticação junto com a requisição, o que é adequado para acesso baseado em token. Como alternativa, emita uma URL assinada de curta duração que conceda acesso a exatamente um documento por um curto período.
Use um token de curta duração com escopo restrito a um único documento. Os cabeçalhos evitam expô-lo na URL, mas não o mantêm em segredo dos parâmetros da Assembly nem dos logs da aplicação. Restrinja o acesso aos registros de Assembly, oculte tokens nos seus próprios logs e defina notification_payload como ["without_params"] para omitir os parâmetros das notificações.
{
"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 fora da URL um token de curta duração com escopo de documento. Trate os parâmetros e os logs da Assembly como sensíveis.
URLs assinadas não reutilizáveis
Conceda acesso a um único documento por um curto período quando a autenticação por cabeçalho não estiver disponível.
Nunca na string de consulta
Credenciais colocadas ali ficam registradas em todo lugar onde a URL renderizada é armazenada.
Faça um documento reemitido ficar idêntico ao original
Uma fatura é um registro usado para fins legais, e a versão que um cliente recebe em março ainda deve ser renderizada de forma idêntica em novembro. Dois hábitos garantem isso. Renderize a partir de uma URL de modelo versionada, para que uma mudança posterior de design não possa alterar um documento já emitido, e armazene o arquivo resultante em vez de gerá-lo novamente sob demanda.
Vale a pena tratar explicitamente documentos montados a partir de várias partes. Use /document/merge com document_1, document_2 e os aliases as seguintes para definir a ordem, e bundle_steps: true para reunir as partes. Isso evita depender dos nomes dos arquivos de entrada ou dar a um segundo serviço acesso às 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"
}
}
}Versione o modelo
Uma mudança de design deve gerar novos documentos, e não alterar retroativamente os que já foram emitidos.
Armazene, não gere de novo
Mantenha o arquivo gerado para que uma reemissão seja uma cópia, e não uma nova renderização.
/document/merge
Combina documentos de várias partes em uma única Assembly; use aliases as explícitos para controlar a ordem.
Mantenha previsível o custo de renderização
A renderização de uma página é mais cara do que uma conversão de formato, porque inicia um navegador, busca sub-recursos e espera a página se estabilizar. Esse custo é aceitável para um documento que um cliente solicitou, e um desperdício quando o mesmo extrato é renderizado de novo toda vez que alguém abre uma visualização em lista. A solução habitual é renderizar uma vez, no momento em que o documento se torna definitivo, e depois servir o arquivo armazenado.
A geração em massa merece um tratamento à parte. Uma execução de fim de mês que produz milhares de extratos não deve concorrer com a renderização pela qual um cliente está esperando, e um delay fixo aplicado a um lote desses se multiplica em tempo e dinheiro reais. Medir o custo por documento emitido, em vez de por Assembly, costuma revelar esses padrões rapidamente.
Renderize na finalização
Gere o arquivo quando o documento se tornar definitivo, não a cada visualização.
Separe as execuções em massa
Mantenha os lotes de fim de mês longe das renderizações pelas quais uma pessoa está esperando.
Audite atrasos fixos
Uma pausa de um segundo passa despercebida uma vez, mas sai cara ao longo de dez mil documentos.
Verifique o documento antes que um cliente o veja
Uma renderização pode ser bem-sucedida e ainda assim estar errada. O Robot retorna um PDF válido independentemente de o gráfico ter sido desenhado ou não, então uma verificação que só pergunta se um arquivo foi produzido não vai detectar uma página em branco. Asserções simples detectam a maior parte dos problemas: um tamanho em bytes plausível, uma contagem de páginas esperada e a presença de uma string conhecida, como o número do documento.
Renderizar para png junto com o PDF durante o desenvolvimento oferece uma verificação visual rápida, fácil de conferir a olho na revisão, e comparar uma renderização nova com uma imagem de referência armazenada detecta regressões de layout que uma verificação de tamanho em bytes não consegue detectar. Nenhuma dessas verificações pertence ao caminho de produção, mas vale a pena manter ambas no pipeline que publica alterações de modelo.
Faça asserções sobre o conteúdo, não sobre a existência
Verifique a contagem de páginas e um identificador conhecido, em vez de apenas verificar se um arquivo existe.
Renderizações em imagem para revisão
Um png da mesma página permite revisar alterações de modelo com uma olhada rápida.
Compare com uma referência
A comparação visual detecta regressões de layout que as verificações de tamanho deixam passar.
Detalhes técnicos que vale a pena conhecer
- O parâmetro format aceita jpeg, jpg, pdf e png. Apenas pdf produz um documento; os demais capturam uma imagem da página.
- O parâmetro omit_background se aplica à saída em imagem e não tem efeito quando format é pdf, portanto a transparência não pode ser levada para o documento.
- O parâmetro wait_until corresponde ao estado de carregamento subjacente do navegador, que é a forma confiável de esperar por fontes, gráficos e dados carregados tardiamente antes de o instantâneo ser capturado.
- O parâmetro delay adiciona uma pausa fixa depois que o estado de carregamento é atingido. É um recurso pouco preciso que aumenta o custo e a latência de cada renderização, por isso prefira um wait_until mais específico sempre que possível.
- Uma fatura renderizada é um registro usado para fins legais. Renderizar a partir de uma URL de modelo imutável e armazenar o arquivo resultante, em vez de gerá-lo novamente sob demanda, mantém uma cópia reemitida idêntica à original.
- Como a renderização executa um navegador real, a página precisa estar acessível a partir da Transloadit. Páginas protegidas por um cookie de sessão precisam de uma URL assinada de uso único ou das credenciais passadas pelo parâmetro headers.
Uma abordagem prática
- 1
Crie o documento como uma página normal com uma folha de estilo de impressão e verifique-o primeiro em um navegador.
- 2
Renderize-o com /html/convert usando o formato pdf e um wait_until explícito.
- 3
Armazene o resultado em um bucket privado junto com os identificadores que o produziram. Use bucket-default para buckets S3 com ACLs desativadas e aplique o controle de acesso pela política do bucket.
- 4
Mescle as páginas complementares em um único arquivo com /document/merge quando o documento tiver várias partes.
Quando a Transloadit é útil
Use /html/convert com o formato pdf quando o documento já existir como página web ou puder ser renderizado como uma. Aponte-o para uma url ou faça upload de HTML e deixe o Robot renderizar o arquivo enviado. Combine-o com /document/merge quando várias páginas precisarem ficar em um único arquivo.
Limite da arquitetura
/html/convert renderiza uma página com um navegador headless, então produz uma cópia visual paginada, e não um PDF acessível e com tags. Documentos que precisam de estrutura selecionável, campos de formulário ou formatos de arquivamento de longo prazo, como PDF/A, devem ser produzidos por um gerador de documentos dedicado.
Perguntas frequentes
Por que meu PDF está sem gráficos ou fontes?
Quase certamente o instantâneo foi capturado antes que esses recursos terminassem de carregar. Defina wait_until com um estado de carregamento que cubra a dependência. Adicione delay somente se um estado de carregamento não puder expressá-la, lembrando que a pausa é cobrada em cada renderização.
Posso gerar um PDF com fundo transparente?
Não. omit_background afeta a saída de imagem e não tem efeito quando format é pdf. Se a transparência for necessária, renderize em png no lugar disso e insira essa imagem em um documento.
Como renderizo uma página que exige login?
Passe a autenticação pelo parâmetro headers ou emita uma URL assinada de curta duração, restrita a esse único documento. Evite colocar credenciais na string de consulta, porque a URL renderizada fica registrada em todos os logs que registram a renderização.
A saída é um PDF acessível e com tags?
Não. Um navegador headless produz uma cópia visual paginada, e não um documento com tags que tenha ordem de leitura, campos de formulário ou conformidade com PDF/A. Requisitos desse tipo exigem um gerador de documentos dedicado, e não a renderização de uma página.
Como combino várias páginas renderizadas em um único arquivo?
Renderize cada parte e passe os resultados para /document/merge na mesma Assembly. Atribua os aliases document_1, document_2 e os demais aliases as e ative bundle_steps: true. Sem aliases explícitos, o Robot ordena pelo nome do arquivo, e não pela ordem dos nomes dos Steps no array.