Having two isolated (in terms of history/cookies/localstorage) BrowserViews in the same BrowserWindow with Electron Having two isolated (in terms of history/cookies/localstorage) BrowserViews in the same BrowserWindow with Electron google-chrome google-chrome

Having two isolated (in terms of history/cookies/localstorage) BrowserViews in the same BrowserWindow with Electron


So, I managed to get this working but in a very, very, roundabout way. Effectively session hijacking your own session, saving and loading it on app close/open. Code below with some comments, prefaced with some useful links. This worked when running as dev, and when running with a build application.

You may need to look into possible security issues here with storing cookies locally like this.

The only thing I have not tackled in this answer is:

keep history ... after restart of the Electron app



const { app, BrowserWindow, BrowserView, globalShortcut, session } = require('electron');const eJSONStorage = require('electron-json-storage');// Our two different sesions, views, and base URL for our 'tabs'.let bv1Session, bv2Session = session;let bv1, bv2 = BrowserView;const appTabUrl = 'https://www.twitter.com';app.on('ready', () => {  const width = 1200; const height = 600;  let b1Active = true;  // Our browser window  browserWindow = new BrowserWindow({    width: width,    height: height,  });  // Our first browser window with it's own session instance.  bv1Session = session.fromPartition('persist:bv1Session', { cache: true });  bv1 = createBrowserView(appTabUrl, bv1Session, width, height);  loadCookieState('view1Cookies', bv1Session);  // Our second browser window with it's own session instance.  bv2Session = session.fromPartition('persist:bv2Session', { cache: true });  bv2 = createBrowserView(appTabUrl, bv2Session, width, height);  loadCookieState('view2Cookies', bv2Session);  // Our initial setting of the browserview  browserWindow.setBrowserView(bv1);  // Our shortcut listener and basic switch mechanic  // Set to [CTRL + /] for windows or [CMD + /] for OSX  globalShortcut.register('CommandOrControl+/', () => {    b1Active ? browserWindow.setBrowserView(bv2) : browserWindow.setBrowserView(bv1);    b1Active = !b1Active  });});// When the app closes, exit gracefully.// Unregister keypress listener, save cookie states, exit the app.app.on('window-all-closed', () => {  globalShortcut.unregisterAll();  saveCookieState('view1Cookies', bv1Session);  saveCookieState('view2Cookies', bv2Session);  app.quit();})// Helper method to generate a browser view.function createBrowserView(url, session, width, height) {  let browserView = new BrowserView({    webPreferences: {      nodeIntegration: false,      nodeIntegrationInWorker: false,      session: session    }  });  browserView.setBounds({ x: 0, y: 0, width: width, height: height });  browserView.webContents.loadURL(url);  return browserView;}// Method that takes a session name, and our current session to save its state.function saveCookieState(sessionName, currentSession) {  currentSession.cookies.get({}, (_, cookies) => {    cookies.forEach(cookie => {      // URL is a required paramater, take it from the domain with a little parsing.      // Twitter always uses HTTPS otherwise, we would need to check for http vs https too.      const cDomain = !cookie.domain.startsWith('.') ? `.${cookie.domain}` : cookie.domain;      cookie.url = `https://www${cDomain}`    });    // Save the set of cookies against the session name.    eJSONStorage.set(sessionName, cookies, err => {      if (err) {        throw err;      }    });  });}// Method that loads a session based on its name, into a session created by us.function loadCookieState(sessionName, currentSession) {  eJSONStorage.get(sessionName, (error, cookieData) => {    // Check for empty object returned, this means no saved sessions.    if (Object.entries(cookieData).length === 0) {      return;    }    if (error) {      throw error;    }    // If we have saved sessions and no errors, load the sessions.    cookieData.forEach(cookie => currentSession.cookies.set(cookie, error => {      if (error) console.error(error);    }));  });}