DEMOS / Live Component

Downloading Files

Return LiveResponse::downloadUrl() for a file served by its own route, or LiveResponse::downloadFile() for content built by a LiveAction. LiveComponent renders state changes and delivers queued events before starting the download.

ux.symfony.com

Download from a URL

Send the browser to a dedicated download route.

0 downloads

Generate a file

Build and send a text report from the current counters.

0 downloads

Download with events

Emit a LiveComponent event, dispatch a browser event, then send the file.

0 events

0 downloads total

Download from a URL

Generate the URL of a dedicated download route, then return it with downloadUrl(). LiveComponent renders the updated counters first. The browser then makes a separate GET request.

Choose this for files served by their own route, especially large or resumable downloads.

81#[LiveAction]
82public function downloadUrl(
83    UrlGeneratorInterface $urlGenerator,
84): LiveResponse {
85    ++$this->urlDownloads;
86    ++$this->totalDownloads;
87
88    $downloadUrl = $urlGenerator->generate(
89        'app_demo_live_component_live_download_document',
90    );
91
92    return LiveResponse::downloadUrl($downloadUrl);
93}

Generate a file in the action

Pass a Closure to downloadFile() when the action builds the file. Here, the closure yields a text report line by line without writing a temporary file.

LiveComponent renders the updated counters and filename before the download starts. The browser buffers the content before saving the report.

 95#[LiveAction]
 96public function downloadGeneratedFile(): LiveResponse
 97{
 98    ++$this->fileDownloads;
 99    ++$this->totalDownloads;
100
101    $number = $this->fileDownloads;
102    $total = $this->totalDownloads;
103    $filename = "live-report-{$number}.txt";
104    $this->lastGeneratedFilename = $filename;
105
106    $lines = [
107        "Symfony UX LiveComponent report\n",
108        "Report number: {$number}\n",
109        "Total downloads: {$total}\n",
110    ];
111
112    return LiveResponse::downloadFile(
113        static function () use ($lines): iterable {
114            foreach ($lines as $line) {
115                yield $line;
116            }
117        },
118        filename: $filename,
119        contentType: 'text/plain; charset=UTF-8',
120    );
121}

Download with events

Call emit() and dispatchBrowserEvent() before returning downloadFile(). LiveComponent renders the updated counters, emits download, dispatches the matching browser event, then starts the download.

123#[LiveAction]
124public function downloadFileWithEvents(): LiveResponse
125{
126    ++$this->totalDownloads;
127
128    $eventData = [
129        'filename' => 'live-components.md',
130    ];
131
132    $this->emit(
133        self::DOWNLOAD,
134        $eventData,
135    );
136    $this->dispatchBrowserEvent(
137        self::DOWNLOAD,
138        $eventData,
139    );
140
141    $file = new \SplFileInfo($this->downloadDocumentPath);
142
143    return LiveResponse::downloadFile(
144        $file,
145        contentType: 'text/markdown; charset=UTF-8',
146    );
147}
Author smnandre
Published 2026-08-04