Troubleshooting common issues
Speeding up initial load of the Persona integration
The Persona JS SDK functions by rendering an iframe
that loads Persona's Hosted Flow Integration. Loading the assets needed can take a significant amount of time on low-quality connections. We provide several APIs and recommendations for improving initial load.
Preloading JavaScript assets
The SDK client provides a Client.preload()
method that preloads the necessary assets into the browser's cache. Calling this method before calling new Client(...)
can speed up initial load times. For more information, see Client Methods.
Eagerly instantiating Persona client
We generally recommend instantiating the Persona client as early as possible based on when the user signals intent to begin the flow, and calling open()
on the client instance once the flow is ready to be displayed. This allows the Persona flow to begin loading in the background.
Opening widget onReady
instead of onLoad
onReady
instead of onLoad
We provide two client callbacks related to initial load. onLoad
fires when the iframe
finishes loading, but the contents have not yet loaded, while onReady
fires when the contents have loaded and are ready for user interaction. Opening the widget onReady
and handling loading UI on your side can provide a smoother experience.
Ensure geographical routing is set if required
If your users are outside of the US, not specifying geographical routing will result in significantly increased latency. Use the routingCountry
parameter to specify geographical routing if needed.
Refused to display 'https://withpersona.com/' in a frame because it set 'X-Frame-Options' to 'deny'
What this means
This error message is a result of a security feature that Persona offers when you integrate Persona using Embedded Flow.
Persona lets you specify, via an allowlist, which domains can load the embedded flow. You should specify only the domains where you embed your Persona flow. Potential attackers will then be blocked from embedding and loading your flow on their domain.
If you see this error, it means that the domain the embedded flow in being loaded on is not on the allowlist.
How to fix
If you see this error, go to the Embedded Flow integration page in the Persona Dashboard, and locate "Step 3 Configure allowed domains". Here, you'll see the Domain allowlist.
Ensure that:
- The domain from which you are trying to load the Embedded Flow (and where you're seeing the error message) is on the Domain allowlist.
- The domain in the Domain allowlist is correctly spelled and properly formatted. Note: a domain name should NOT include the
http://
orhttps://
part of the URL.
If you are testing, please note:
localhost
is enabled by default for Inquiries created in your Sandbox environment.localhost
must be manually added to be usable for Production inquiries.
If you have a more complex setup, please note:
- If your embedded flow is loaded on a webpage that is itself loaded as an iframe on another parent webpage, you must specify all parent origins by setting the
frameAncestors
option in the JS SDK. See Parameters for details.
High memory usage in browser
If you are seeing elevated memory usage, ensure you are not repeatedly calling new Persona.Client({ ... })
without cleaning up old clients with client.destroy()
. Calling new Persona.Client({ ... })
multiple times without cleanup will load multiple instances of the Persona web flow via iframe
, which will quickly consume available memory even if the iframe
s are not visible on the screen.
Server rendering
The Persona JS SDK requires client-side JavaScript and cannot be server rendered. If you are using a server rendered framework such as next.js or Remix, you will need to use the framework's client rendering escape hatch.
next.js
This error will manifest as ReferenceError: self is not defined when using next.js
. To solve the problem, add the following snippet:
import dynamic from "next/dynamic";
export const PersonaInquiry = dynamic(
() => import('persona').then((module) => module.Client),
{ssr: false}
);
Remix
Dynamically import the embedded flow with
import { useEffect, useState } from "react";
export default function PersonaInquiry() {
const [clientLoaded, setClientLoaded] = useState<boolean>(false);
useEffect(() => {
import('persona').then((module) => {
// interact with module.Inquiry based on your integration
});
}, []);
// coordinate UI with clientLoaded
}
PDFs linked from the Inquiry flow cannot be loaded
Links that trigger PDFs to open in a popup require relaxing iframe
sandbox restrictions via the allow-top-navigation-by-user-activation
attribute. Note that relaxing sandbox restrictions has security implications and should be done with care.
Note that if you are testing your integration with an iframe
-based tool such as JSFiddle, Codepen, or CodeSandbox, you may still see issues. This is because the Persona iframe
is nested within the tool's own iframe
, which has its own set of sandbox attributes. To properly test, use a local HTML file.
For more information, see iframe sandbox attributes.
I am running into issues when testing locally
If testing locally, ensure your webpage is served by a local web server instead of being opened as a static file. This is due to the origin for local files (file://
) not being a valid origin for window.postMessage()
, which the Persona flow uses to communicate with your code.
For example:
python -m http.server
open http://localhost:8000/your_html_file.html
If you are testing on a mobile device and are running into camera permission errors, you will need to serve your webpage over HTTPS. Browsers restrict insecure origins from accessing certain hardware features. Depending on your testing setup, we recommend:
- Using a service like Codepen or CodeSandbox to host your test page, and then access it over HTTPS.
- Using a tool like ngrok to access your test page over HTTPS.
- Using
mkcert
to generate a certificate and serve HTTPS locally.
If testing using third party services, please ensure that you are not exposing sensitive information about your integration publicly.
Updated 17 days ago