diff --git a/.changeset/wicked-dolphins-tie.md b/.changeset/wicked-dolphins-tie.md
new file mode 100644
index 0000000000..9726195671
--- /dev/null
+++ b/.changeset/wicked-dolphins-tie.md
@@ -0,0 +1,5 @@
+---
+"@rrweb/web-extension": minor
+---
+
+Added session downloader for chrome extension
diff --git a/packages/web-extension/src/pages/SessionList.tsx b/packages/web-extension/src/pages/SessionList.tsx
index b4b5c27cb2..d285932029 100644
--- a/packages/web-extension/src/pages/SessionList.tsx
+++ b/packages/web-extension/src/pages/SessionList.tsx
@@ -31,7 +31,7 @@ import { VscTriangleDown, VscTriangleUp } from 'react-icons/vsc';
import { useNavigate } from 'react-router-dom';
import { type Session, EventName } from '~/types';
import Channel from '~/utils/channel';
-import { deleteSessions, getAllSessions } from '~/utils/storage';
+import { deleteSessions, getAllSessions, downloadSessions } from '~/utils/storage';
import {
FiChevronLeft,
FiChevronRight,
@@ -292,24 +292,38 @@ export function SessionList() {
))}
{Object.keys(rowSelection).length > 0 && (
-
+
+
+
+
)}
diff --git a/packages/web-extension/src/utils/storage.ts b/packages/web-extension/src/utils/storage.ts
index cfd2f1ee18..766ba86fba 100644
--- a/packages/web-extension/src/utils/storage.ts
+++ b/packages/web-extension/src/utils/storage.ts
@@ -88,3 +88,22 @@ export async function deleteSessions(ids: string[]) {
return Promise.all([eventTransition.done, sessionTransition.done]);
});
}
+
+export async function downloadSessions(ids: string[]) {
+ for (const sessionId of ids) {
+ const events = await getEvents(sessionId);
+ const session = await getSession(sessionId);
+ const blob = new Blob([JSON.stringify({ session, events }, null, 2)], {
+ type: 'application/json',
+ });
+
+ const url = URL.createObjectURL(blob);
+ const a = document.createElement('a');
+ a.href = url;
+ a.download = `${session.name}.json`;
+ document.body.appendChild(a);
+ a.click();
+ document.body.removeChild(a);
+ URL.revokeObjectURL(url);
+ }
+}