Dcc.send_bytes/download on clientside

here is an example of downloading a .zip-file using clientside callbacks. Might be useful for some :man_shrugging:

from dash import Dash, html, dcc, Input, Output, no_update
import io
import zipfile
import json

app = Dash(__name__)

app.layout = html.Div([
    html.Button('Download Clientside', id='button1'),
    html.Button('Download normal', id = 'button2'),
    dcc.Download(id = 'download')

function (n){
    var zip = new JSZip();

    zip.file('mydata.json', JSON.stringify(["mydata2"]));

    return zip.generateAsync({ type: "base64" })
        .then(function (base64String) {
            return {'content': base64String, 'filename': 'data.zip', 'type': null, 'base64': true};
        .catch(function (error) {
            console.error("Error generating zip: ", error);
            return dash_clientside.no_update;

    Output('download', 'data'),
    Input('button1', 'n_clicks'),
    prevent_initial_call =True

    Output('download', 'data', allow_duplicate=True),
    Input('button2', 'n_clicks'),
    prevent_initial_call =True
def send_download(n):
    if not n:
        return no_update
    bytes_io = io.BytesIO()
    with zipfile.ZipFile(bytes_io, 'w') as zipf:
            zipf.writestr('mydata.json', json.dumps(["mydata"]))
    sended_bytes  = dcc.send_bytes(bytes_io.getvalue(), "data.zip")
    return sended_bytes

if __name__ == '__main__':

you also need to include jszip.min.js in your assets folder.


Cool and useful example. Thanks for sharing, @Louis :clap:

1 Like