Search code examples
reactjsnext.js

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?


Solution

  • 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>