Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement file Download button in Next.js? (window is not defined)

I know 'window' or 'document' objects are not recognizable in React component before component mounts.

I'm trying to make a download button which receive processed excel file from the backend server. Before I'm using React I used to implement like this...

 <button onclick="download()">Download</button>
    <script>
        function download() {
            const URL = 'http://dynamic-link.com/sample.xlsx'
            window.location.href = URL
        }
    </script>

However, in Next.js or React, window object is not recognizable so I had to do the other way. Download URL is dynamic so I won't use next.config.js

pages/index.tsx

//...
const handleDownloadExcel = () => {
    router.push('/download')
  }
//...
return(
//...
      <button onClick={() => handleDownloadExcel()}>Download!</button>
//...

pages/download.tsx

import { useEffect } from 'react'
import { useRouter } from 'next/router'
const DownloadPage = () => {
    const router = useRouter();
    useEffect(() => {
        //I will pass this URL variable by props later on.
        const URL = 'http://dynamic-url.com/sample.xlsx'
        window.location.href = URL;
        router.push('/')
    }, [])

    return (
        <>
        </>
    )
}

export default DownloadPage;

Now I managed to download a file from server but it doesn't seem right. Is there any other way to do this?

like image 417
loone96 Avatar asked Sep 12 '25 17:09

loone96


2 Answers

Use the file-saver package to download our file.

To install it, run:

npm i file-saver

Then we can call the saveAs function from the package by writing:

import React from "react";
import { saveAs } from "file-saver";

export default function App() {
  const saveFile = () => {
    saveAs(
      "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
      "example.pdf"
    );
  };
  return (
    <div>
      <button onClick={saveFile}>download</button>
    </div>
  );
}

The first argument is the URL to download and the 2nd argument is the file name of the downloaded file.

like image 151
Mayaram Yadav Avatar answered Sep 14 '25 07:09

Mayaram Yadav


You can use the window object in next js like this :

    <script>
        function download() {
            const URL = 'http://dynamic-link.com/sample.xlsx'
            if (typeof window !== "undefined"){
              window.location.href = URL
            }
        }
    </script>
like image 37
Mahdi Faraji Avatar answered Sep 14 '25 08:09

Mahdi Faraji