Skip to content

Commit 507bb47

Browse files
dmortalclaude
andauthored
fix(Dashboard): unblock paystub download — drop noopener and defer blob URL revoke (#1915)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent fa9e0b0 commit 507bb47

1 file changed

Lines changed: 10 additions & 2 deletions

File tree

src/components/Employee/Dashboard/JobAndPayView.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,9 @@ export function JobAndPayView({
120120

121121
const handlePaystubDownload = useCallback(
122122
async (payrollUuid: string) => {
123-
const newWindow = window.open('', '_blank', 'noopener,noreferrer')
123+
// Omit `noopener` — it makes window.open return null in modern browsers,
124+
// which would leave us unable to navigate the new tab to the blob URL.
125+
const newWindow = window.open('', '_blank')
124126
const loadingMessage = t('jobAndPay.paystubs.downloadLoadingMessage')
125127
if (newWindow) {
126128
// Avoid the user staring at about:blank while we fetch the PDF. The
@@ -158,9 +160,15 @@ export function JobAndPayView({
158160
const pdfBlob = await readableStreamToBlob(response.value.responseStream, 'application/pdf')
159161
const url = URL.createObjectURL(pdfBlob)
160162
if (newWindow) {
163+
// Revoke after the new tab has loaded the blob; revoking synchronously
164+
// would race the navigation and leave the tab blank.
165+
newWindow.addEventListener('load', () => {
166+
URL.revokeObjectURL(url)
167+
})
161168
newWindow.location.href = url
169+
} else {
170+
URL.revokeObjectURL(url)
162171
}
163-
URL.revokeObjectURL(url)
164172
} catch (err) {
165173
if (newWindow) {
166174
newWindow.close()

0 commit comments

Comments
 (0)