index.tsx
1 import { MouseEvent, ReactNode, useCallback } from 'react'; 2 import { Version } from '@site/src/constants'; 3 4 interface NotebookDownloadButtonProps { 5 children: ReactNode; 6 href: string; 7 } 8 9 export function NotebookDownloadButton({ children, href }: NotebookDownloadButtonProps) { 10 const handleClick = useCallback( 11 async (e: MouseEvent) => { 12 e.preventDefault(); 13 14 if ((window as any).gtag) { 15 try { 16 (window as any).gtag('event', 'notebook-download', { 17 href, 18 }); 19 } catch { 20 // do nothing if the gtag call fails 21 } 22 } 23 24 if (!Version.includes('dev')) { 25 // Replace 'master' with the current version to pin the download to the released version 26 // and avoid 404 errors 27 href = href.replace(/\/master\//, `/v${Version}/`); 28 } 29 30 const response = await fetch(href); 31 const blob = await response.blob(); 32 33 const url = window.URL.createObjectURL(blob); 34 const link = document.createElement('a'); 35 link.style.display = 'none'; 36 link.href = url; 37 const filename = href.split('/').pop(); 38 link.download = filename; 39 40 document.body.appendChild(link); 41 link.click(); 42 43 window.URL.revokeObjectURL(url); 44 document.body.removeChild(link); 45 }, 46 [href], 47 ); 48 49 return ( 50 <a 51 className="button button--primary" 52 style={{ marginBottom: '1rem', display: 'block', width: 'min-content' }} 53 href={href} 54 download 55 onClick={handleClick} 56 > 57 {children} 58 </a> 59 ); 60 }