diff --git a/src/app/groups/[groupId]/expenses/export/csv/route.ts b/src/app/groups/[groupId]/expenses/export/csv/route.ts index dfb92c7b5..46b7ae1b5 100644 --- a/src/app/groups/[groupId]/expenses/export/csv/route.ts +++ b/src/app/groups/[groupId]/expenses/export/csv/route.ts @@ -151,13 +151,23 @@ export async function GET( const csv = json2csvParser.parse(expenses) const date = new Date().toISOString().split('T')[0] - const filename = `Spliit Export - ${group.name} - ${date}.csv` + + // Create an ASCII-safe version of the group name for the 'filename' parameter + const asciiSafeGroupName = group.name.replace(/[^\x00-\x7F]/g, '_') // Replace non-ASCII with underscore + const asciiFilename = `Spliit Export - ${asciiSafeGroupName} - ${date}.csv` + + // Use the original group name for the 'filename*' parameter (UTF-8 encoded) + const fullFilename = `Spliit Export - ${group.name} - ${date}.csv` + const encodedFullFilename = encodeURIComponent(fullFilename) // \uFEFF character is added at the beginning of the CSV content to ensure that it is interpreted as UTF-8 with BOM (Byte Order Mark), which helps some applications correctly interpret the encoding. return new NextResponse(`\uFEFF${csv}`, { headers: { 'Content-Type': 'text/csv; charset=utf-8', - 'Content-Disposition': contentDisposition(filename), + 'Content-Disposition': contentDisposition(fullFilename, { + type: 'attachment', + fallback: asciiFilename, + }), }, }) }