Back to top

Session continuation

Setting up a continuation point

The power of Surfly co-browsing lays in its proxy approach. It is through our proxy that data is transferred from the original website to the Surfly session and is synchronized to all the participants. This is done seamlessly, but in some cases an extra implementation might be needed: session continuation. This is optional, but in doing so, you make sure that the necessary info is transferred from the user’s current browser session to the co-browsing session. For example: if your user has filled up their shopping cart, you would want them to keep the contents of the cart when a Surfly session is initiated. In some cases you would need session continuation to make this possible.

By default we apply state transfer, this includes the transfer of all non-HTTP-only cookies. By default we assume that the scope is “path”: “/”, “domain”: “”. Furthermore, we also transfer browser storage and form fields. Meaning that in most cases, the transition from the website to a co-browsing session will be seamless.

The state transfer becomes a bit more tricky when you want to transfer HTTP-only cookies. These cookies might contain essential information for the browser session to work properly, but due to the HTTP-only flag, Surfly can’t access them by default and therefore we can’t read the full request. To make sure that this information is available inside the co-browse session, it is important to set up a continuation point.

Transferring the state

When the user initiates a co-browsing session, a co-browsing view is opened on top of the original web page, and within this new window (which is called an iframe) the co-browse session starts. The co-browse session is a proxied version of the original web page, and therefore the browser recognizes it as a different web session. For your users, it will almost have the same effect as when you refresh the page.

Example: Shopping Cart

A user is browsing through a shopping website. While they navigate through the website, pieces of data are stored in different ways, like in cookies for instance. In one of these cookies, the contents of the user’s shopping cart is saved. The user then struggles filling in the payment form, and they seek help from a support agent. They start a co-browsing session, and an iframe containing the co-browsing session opens on top of the original website. The user doesn’t see much of a difference, except for the second cursor on the screen that belongs to the agent. But then they proceed to the checkout page and all of a sudden the shopping cart is empty. Surfly wasn’t able to read the data in the cookie, because it has an HTTP-only flag, so the contents of the shopping cart was not transferred to the co-browsing session.


A user’s browser communicates with your website’s server through HTTP: a request/response protocol. The browser sends a request each time your users navigate on your website, and the server responds with data that the browser then translates into something the user can understand.

HTTP itself is stateless: it does not store any data. So for your browser to actually save a certain state (to remember the contents of your shopping cart for instance), different solutions are needed. Cookies are one of them, and they allow the server to store data on the client’s side, in the browser. This can be stored on memory or on disk. Once a cookie is set, by default it will be send with each next request that you make to the same exact host.

The cookies are added to the request as one of the request headers and they contain specific variables: name, value, domain, path and expiration date. It might also carry a flag: HTTP and/or secure. When a browser makes a request to the website’s server, the server reads the values of the cookie in the request, interprets it and adjusts its behaviour accordingly.

Example: logging in

When you log in to a website, Facebook for instance, your logged-in state is saved in a cookie. With each action that you perform on Facebook, an HTTP request is send to the Facebook servers, so your login cookie is send each time. If this weren’t to happen, you would be logged out of Facebook immediately when you navigate to a different page.

Browser storage

Next, there’s also browser storage, which consists out of sessionStorage (erased when you close the entire browser) and localStorage (persistent). What is stored are also bunches of variables, which can be accessed through Javascript. It’s similar to a cookie, but in contrary, it is not send with HTTP requests. The advantage of using browser storage is that you can store bigger chunks of data.

Form continuation

Use-case: Claims Form

Your client has lost his luggage on vacation and he’s filling in the claims form on your website. He gets confused and he needs help filling in the form. The client calls your contact center and the agent who picks the call, directs him to the co-browse button on the website. The co-browse session starts and the agent joins your client on the form page.

Through state transfer we are able to transfer form data to the co-browse session. Even when your website doesn’t store form data in browser storage or in a cookie, in most cases we can still transfer the data to the co-browse session.

You can check if the data in your form fields are stored by refreshing the page. If the form fields are emptied on a page refresh, this means that your website doesn’t store the values anywhere. In this case, at the start of the co-browse session, Surfly will still try to scan the form fields and transfer their contents to the session, but we can’t repeat this process at the end of the session. Furthermore, dynamic forms (like the ones you see in a single-page application) are not supported. We therefore always recommend to store form data in browser storage or in a cookie.

Transferring HTTP-only cookies

Unlike non-HTTP-only cookies and browser storage, cookies with an HTTP-only flag can’t be accessed through Javascript. So why apply this flag? It’s a security measure. If you’re running scripts on your website that you don’t trust (from third parties for instance), it’s good to add this to your cookies. It ensures that cookies with an HTTP-only flag are only accessible on your server.

This does mean that, if you want to ensure a seamless co-browsing experience and transfer the contents of a shopping cart or the logged in state of your users to the co-browsing session, an extra measure has to be implemented to ensure the transfer of all cookies: a continuation point. This also goes for form data that is stored in HTTP-only cookies.

Note: Due to the browser cookie handling policies or security limitations of cross-site cookies, back transfer works in a limited way when the Leader is using Chrome or Firefox or the website does not use HTTPS encryption. On session end, webStorage (localStorage + sessionStorage) is transferred back but cookies (regular + HttpOnly) are not

To summarize, the difference between state transfer and session continuation is:

State Transfer Session Continuation
sessionStorage checkmark checkmark
localStorage checkmark checkmark
Form fields checkmark checkmark
non-HTTP-only cookies checkmark checkmark
HTTP-only cookies x-icon checkmark
Cookies with paths other than “/” checkmark x-icon

Session continuation setup

Since HTTP-only cookies are only accessible on your own servers, Surfly has to act like your server to be able to receive the cookies in order to ensure session continuation. You can do this by setting up a continuation point. This is a special section on your website,, which proxies requests to the Surfly server.

When set up correctly and you start a co-browsing session on your website, automatically a new request is created and sent to This request will contain all the cookies. The Surfly server can then grab the cookies, including the HTTP-only cookies. This way, Surfly can securely include HTTP-only cookies within the co-browsing session, therefore ensuring a seamless co-browsing experience.

Note: because the continuation point is located at a specific URL, it cannot capture cookies that have the Path attribute set to something else than “/”.

Warning! It is very important that all requests whose URLs start with /surfly_cookie_transfer/ are being passed through as-is. Any extra manipulation on HTTP requests and HTTP responses (except the required request headers described below) may break the session continuation. In particular, it is recommended to disable WAF filtering, and custom error pages on these URLs.

Typical Continuation Point setup


Setting up a continuation point usually only requires a small adjustment to your load balancer. The setup entails that you grant the Surfly server access to this specific path only. When a Surfly session is started, your server needs to forward all HTTP requests for the path /surfly_cookie_transfer/* to the Surfly server. If you have implemented Surfly on more than just one domain, if your website sets cookies on multiple subdomains, or if a website is served over HTTPS and HTTP, you may need to setup multiple continuation points. For example, if you store a user authentication token on, but also keep shopping cart cookies on

*Important: Due to the way how browsers isolate cookies on different domains, it is currently not possible to transfer cookies from domains that don’t share a common TLD+1 suffix with the starting page. For example, if you are starting a session from a page on, you will be able to transfer cookies from and, but cookies from will be ignored. To workaround this problem, you can change the integration script to first relocate the user to a page in zone, and start a session from there. In this case, cookies from will be transferred. You can then use JS API to relocate the cobrowsing window back to

You can find example configurations for popular load balancers below. Note that there might be slight differences, depending on versions.


Add these lines in your config file:

location /surfly_cookie_transfer/ {
    proxy_redirect off;
    proxy_set_header X-Continuation-Origin;
    proxy_set_header X-Widget-Key **Widget key here**;


frontend example-com-https
  acl surfly_session_continuation hdr(host) -i path_beg /surfly_cookie_transfer/
  use_backend surfly_continuation_point_https if surfly_session_continuation
  ...your custom configuration here...

backend surfly_continuation_point_https
   http-request set-header X-Widget-Key **Widget key here**
   http-request set-header Host
   server surfly ssl


Make sure you have mod_ssl, mod_proxy, mod_proxy_http, and mod_headers modules installed and loaded, see this tutorial for details):

SSLProxyEngine On

<Location "/surfly_cookie_transfer/">
   RequestHeader set X-Continuation-Origin ""
   RequestHeader set X-Widget-Key "**Widget key here**"
   ProxyPass ""

Custom continuation point

If you cannot make use of the configs above, you can implement the continuation point by other means (for example, in a server-side script). Here is what a continuation point is expected to do:

  • It should pass all HTTP(S) requests which paths start with /surfly_cookie_transfer/ to the Surfly server.

  • Host header must contain the host of the Surfly server (e.g. if you’re proxying to our main production server

  • It must add two additional request headers: X-Widget-Key and X-Continuation-Origin:

    • X-Widget-Key must contain your widget key
    • X-Continuation-Origin must contain an Origin of your website. That is, a protocol scheme followed by domain name and a port in case it is non-standard. For example, a continuation point at should set X-Continuation-Origin to "“. Note that the protocol scheme matters in this case (”" and "" are different origins).

Verifying the continuation point

Once you’ve set up the continuation point, you can check the session continuation status by typing in your domain, and adding /surfly_cookie_transfer/ to the end. For example, That page will execute a quick check, and report if there are some problems detected. If any of the boxes are red, it means that your continuation point is not set up correctly. Click the “?” of the respective box for instructions on how to adjust this. For instance, you might find that the bottom box will light up red. This has to do with the company domain settings.


Updating your Surfly settings

The next step is to update the following options:

  • add all continuation points to the cookie_transfer_urls list

  • cookie_transfer_proxying must be set to to true

  • set cookie_transfer_scopes. Within the cookie transfer scopes, you need to specify all the cookies you want to transfer. So this also includes the non-httpOnly cookies.

Note: If you want to only change the cookie scopes but you don’t require a continuation point, you can also only update the cookie_transfer_scopes option. In this case you must not set cookie_transfer_urls or cookie_transfer_proxying.

Finally, your session continuation settings might look something like this:

    cookie_transfer_enabled: true,
    cookie_transfer_proxying: true,
    cookie_transfer_urls: ["", "", ""],
    cookie_transfer_scopes: [
      {"path": "/", "domain": "", "name": "cookie1", "httponly": true},
      {"path": "/", "domain": "", "name": "cookie2", "httponly": true},
      {"path": "/", "domain": "", "name": "cookie3", "httponly": true},
      {"path": "/", "domain": "", "name": "cookie4", "httponly": false}  // a host-only cookie, note the domain without a leading dot

Note: you can also update these settings in the Surfly dashboard

When you check your continuation point status page again, it should look like this:


Generated by aglio on 17 Aug 2022