Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

5.1K
Visualizações
How to download a file on Next.js using an API route

I'm using next.js. I have a 3rd party service I need to retrieve a PDF file from. The service requires an API key that I don't want exposed on the client side.

Here are my files

/api/getPDFFile.js ...

  const options = {
    method: 'GET',
    encoding: 'binary',
    headers: {
      'Subscription-Key': process.env.GUIDE_STAR_CHARITY_CHECK_API_PDF_KEY,
      'Content-Type': 'application/json',
    },
    rejectUnauthorized: false,
  };

  const binaryStream = await fetch(
    'https://apidata.guidestar.org/charitycheckpdf/v1/pdf/26-4775012',
    options
  );
  
  return res.status(200).send({body: { data: binaryStream}}); 


pages/getPDF.js

   <button type="button" onClick={() => {
  fetch('http://localhost:3000/api/guidestar/charitycheckpdf',
    {
      method: 'GET',
      encoding: 'binary',
      responseType: 'blob',
    }).then(response => {
      if (response.status !== 200) {
        throw new Error('Sorry, I could not find that file.');
      }
      return response.blob();
    }).then(blob => {
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.style.display = 'none';
      a.href = url;
      a.setAttribute('download', 'test.pdf');
      document.body.appendChild(a);
      a.click();
      window.URL.revokeObjectURL(url);
    })}}>Click to Download</button>

Clicking the button downloads a file, but when I open it I see the error message, "Failed to load PDF document."

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

You appear to be using node-fetch. So, you can do something like this:

// /pages/api/getAPI.js

import stream from 'stream';
import { promisify } from 'util';
import fetch from 'node-fetch';

const pipeline = promisify(stream.pipeline);
const url = 'https://w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf';

const handler = async (req, res) => {
  const response = await fetch(url); // replace this with your API call & options
  if (!response.ok) throw new Error(`unexpected response ${response.statusText}`);

  res.setHeader('Content-Type', 'application/pdf');
  res.setHeader('Content-Disposition', 'attachment; filename=dummy.pdf');
  await pipeline(response.body, res);
};

export default handler;

Then from client:

// /pages/index.js

const IndexPage = () => <a href="/api/getPDF">Download PDF</a>;
export default IndexPage;

CodeSandbox Link (open the deployed URL in a new tab to see it work)

References:

  • API Routes | Next.js
  • Streams | node-fetch
  • How to send a pdf file from Node/Express app to the browser
  • <a>: The Anchor element | MDN

PS: I don't think much error handling is necessary in this case. If you wish to be more informative to your user you can. But this much code will also work just fine. In case of error the file download will fail showing "Server Error". Also, I don't see a need to create a blob URL first. You can directly download it in your app as the API is on the same origin.


Earlier I had used request, also posting it here in case someone needs it:

import request from 'request';
const url = 'https://w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf';
export default (_, res) => { request.get(url).pipe(res); };
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda