Custom Element Sandbox

To improve security we're sandboxing Custom Element and iFrame extensions in the Wix Editor. This means we no longer allow allow-same-origin and as a result your apps/site components will be limited in the ability to write and read sessionStorage, localStorage, cookies, indexDB and cache inside the Editor.

Until now your apps/site components could access the above unprotected, for example: const cookies = document.cookie

Below are some actions you can take to check if you have access to the APIs when running your code.

If you don't have access, make sure your code can handle the flow without these APIs and data.

How to prevent your code from breaking

The common solution to problems in accessing these APIs is wrapping access to them. This can be done either by wrapping calls to each of them or having a function that is passed in an execution and tries it.

Option 1: Wrapping access to an API

1
2
3
4
5
6
7
8
9
let requestedValue = '';
try{
  const cookies = document.cookie;
  // extract requested value from the cookie here
  requestedValue = cookies.split(';').filter(cookieValue => cookieValue.trim().startsWith('myCookieName'));
  requestedValue = requestedValue.length === 1 ? requestedValue[0].trim().split('=')[1] || '' : '';  
} catch (e){
  console.error('access to cookies denied');
}

Option 2: Write a simple function wrapper for running content extraction

1
2
3
4
5
6
7
8
function tryRun(func) {
    try {
        return func();
    }catch(e){
        console.error('Execution failed');        
    }
    return undefined;
}
Then you would wrap the calls to these APIs with it:
1
tryRun(() => document.cookie.split(';'))
After you wrap the calls in one of these manners (or any other standard way), you need your code to assume the data might not exist. So let’s say you rely on a cookie named bob:
1
2
3
4
5
6
7
8
const cookieValue = tryRun(() => {
  const requestedValue = cookies.split(';').filter(cookieValue => cookieValue.trim().startsWith('bob'));
  return requestedValue.length === 1 ? requestedValue[0].trim().split('=')[1] || '' : ''; 
});
if(cookieValue){
   // Handle something here
    console.log(cookieValue);
}

Option 3: Try to access the APIs at the top and set flags / state to be reused later

1
2
3
4
5
6
// If any value returns from document.cookie it means you can use them 
const cookiesEnabled = !!tryRun(
() => {
   document.cookie = 'test=1'; 
   return document.cookie;
});

Option 4: Use browser flags

There are also some flags in the browser you can ask in the browser like navigator.cookiesEnabled, but they are not always consistent across browsers.