Next.js + Transloadit
Use o Uppy em um Client Component e um pequeno endpoint do App Router que assina um Template fixo da Transloadit sem expor o Auth Secret.
Receita executável
Criar a integração
A rota do servidor assina um Template fixo, e o Client Component fornece ao Uppy os params assinados antes de cada upload.
- Crie um Template da Transloadit e coloque o ID dele, a Auth Key e o Auth Secret em variáveis de ambiente do servidor.
- Adicione o Route Handler e proteja-o com as mesmas verificações de autorização do restante da sua aplicação.
- Renderize o Client Component UploadForm em uma página e selecione um arquivo para executar o Template.
Instalar
yarn add @uppy/core @uppy/dashboard @uppy/react @uppy/transloadit transloaditapp/api/transloadit/route.ts
import { NextResponse } from 'next/server'
import { Transloadit } from 'transloadit'
export async function POST() {
const authKey = process.env.TRANSLOADIT_KEY
const authSecret = process.env.TRANSLOADIT_SECRET
const templateId = process.env.TRANSLOADIT_TEMPLATE_ID
if (!authKey || !authSecret || !templateId) {
return NextResponse.json({ error: 'Server configuration is incomplete' }, { status: 500 })
}
const transloadit = new Transloadit({ authKey, authSecret })
const requestParams = {
auth: { expires: new Date(Date.now() + 5 * 60 * 1000).toISOString() },
template_id: templateId,
}
const { params, signature } = transloadit.calcSignature(requestParams)
return NextResponse.json(
{ params, signature },
{ headers: { 'Cache-Control': 'private, no-store' } },
)
}app/UploadForm.tsx
'use client'
import Uppy from '@uppy/core'
import TransloaditPlugin from '@uppy/transloadit'
import Dashboard from '@uppy/react/dashboard'
import { useEffect, useState } from 'react'
import '@uppy/core/css/style.min.css'
import '@uppy/dashboard/css/style.min.css'
export function UploadForm() {
const [uppy, setUppy] = useState<Uppy | null>(null)
useEffect(() => {
const instance = new Uppy().use(TransloaditPlugin, {
waitForEncoding: true,
async assemblyOptions() {
const response = await fetch('/api/transloadit', { method: 'POST' })
if (!response.ok) throw new Error('Could not authorize upload')
return response.json()
},
})
setUppy(instance)
return () => instance.destroy()
}, [])
return uppy == null ? null : <Dashboard uppy={uppy} />
}Autenticação
- Mantenha TRANSLOADIT_SECRET em uma variável de ambiente do servidor sem prefixo. O Next.js expõe aos bundles do navegador as variáveis com o prefixo NEXT_PUBLIC_.
- O Route Handler usa o SDK oficial para Node para assinar o Template ID fixo com validade de cinco minutos e retorna ao navegador apenas os parâmetros e uma assinatura.
- Exija a autorização de usuário de que seu produto precisa antes de retornar uma assinatura e não aceite Template IDs ou Steps arbitrários vindos do navegador.
Limitações e observações operacionais
- O navegador não consegue proteger um Auth Secret. A geração de assinaturas e as verificações de autorização devem permanecer em código exclusivo do servidor.
- waitForEncoding mantém a interface de upload aguardando o processamento. Para Jobs demorados, use Assembly Notifications ou consulte a Assembly mais tarde.
- O exemplo autoriza um único Template fixo. Campos dinâmicos ainda precisam de validação no servidor antes de serem incluídos nos params assinados.
Mais integrações