Guidewire Integration
Before starting your application instrumentation, ensure that you have created an app and have an appKey
Prerequisites
Before installation, confirm the following:
- You have a valid Pyze Application Key
- You know whether your environment is Guidewire Cloud or Self-managed / On-premise
- You know whether you are integrating into:
- Jutro Digital Platform (React-based), or
- Classic PCF UI (PolicyCenter, ClaimCenter, BillingCenter, etc.), or both
- You have permission to add client-side JavaScript and deploy changes in your Guidewire environment
- User browsers can reach
https://unifiedcollector.pyze.com, where the SDK sends events. If a Content Security Policy (CSP) is in force, that domain must be allowed underconnect-src
Installation Options
Choose the method that matches your environment.
| Option | Use When |
|---|---|
| A. Jutro Digital Platform | You are using Guidewire Jutro (portals or digital experiences) |
| B. Classic PCF UI | You need tracking on core InsuranceSuite screens |
Recommended order: Start with Option A when possible.
Option A β Jutro Digital Platform
Method 1: Script Tag
- Open your Jutro project.
- Open the file
public/index.html. - Add the following inside the
<head>section:
<!-- Start Pyze Script -->
<script type="text/javascript">
var pyzeAppKey="YOUR_PYZE_APP_KEY";
!function(e,t){var s=e.Pyze||{_q:[]},i=e.PyzeEvents||{_q:[]},n=e.PyzeCuratedEvents||{_q:[]},r=e.PyzeIdentity||{_q:[]};function p(t,e){function s(e){t[e]=function(){t._q.push([e].concat(Array.prototype.slice.call(arguments,0)))}}for(var i=0;i<e.length;i++)s(e[i])}p(s,["initialize","getTimerReference","getAppInstanceId","postWebAppVersion","postPageView","setUserOptOut","deleteUser"]),p(i,["postCustomEvent","startTimerForEvent","postCustomEventWithAttributes","postTimedEvent","postTimedEventWithAttributes","postExplicitActivation"]),p(n,["post"]),p(r,["setUserProfile","resetUserProfile","updateUserProfile"]);var o=t.createElement("script"),a=t.getElementsByTagName("script")[0];o.type="text/javascript",o.async=!0,o.src="https://cdn.pyze.com/pyze.js",a.parentNode.insertBefore(o,a),e.Pyze=s,e.PyzeEvents=i,e.PyzeCuratedEvents=n,e.PyzeIdentity=r}(window,document),Pyze.initialize(pyzeAppKey);
</script>
<!-- End Pyze Script -->
- Replace
YOUR_PYZE_APP_KEYwith the Pyze App Key obtained from your growth.pyze.com account. - Rebuild and deploy the Jutro application.
Warning
Make sure you replacedYOUR_PYZE_APP_KEY with your own appKey
Method 2: Module Import
- Add the Pyze SDK file to your project.
- In your main entry file (
src/index.jsorsrc/App.js), initialize the SDK:
// Initialize Pyze on application load
Pyze.initialize("YOUR_PYZE_APP_KEY");
- Rebuild and deploy the application.
Option B β Classic PCF UI (Core Screens)
In the classic PCF UI, the Pyze SDK is loaded on the application shell β the single HTML page Guidewire loads after login. All PCF screens are drawn inside the shell without reloading the page, so a script on the shell is present on every screen. Once loaded, the SDK automatically captures page views and user interactions. No changes to individual PCF screens are needed.
Installation is two steps. In each step, choose one method and follow only that method.
- Step 1 β Choose where the Pyze library is loaded from. This gives you one small script, called the loader.
- Step 2 β Add the loader to the Guidewire application shell.
The loader
The loader is a small script that downloads the Pyze library and initializes it with your Application Key:
var pyzeAppKey="YOUR_PYZE_APP_KEY";window.Pyze&&window.pyze_session||!function(e,t){var s=e.Pyze||{_q:[]},i=e.PyzeEvents||{_q:[]},n=e.PyzeCuratedEvents||{_q:[]},r=e.PyzeIdentity||{_q:[]};function o(t,e){for(var s=0;s<e.length;s++)!function(e){t[e]=function(){t._q.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(e[s])}o(s,["initialize","getTimerReference","getAppInstanceId","postWebAppVersion","postPageView","setUserOptOut","deleteUser"]),o(i,["postCustomEvent","startTimerForEvent","postCustomEventWithAttributes","postTimedEvent","postTimedEventWithAttributes","postExplicitActivation"]),o(n,["post"]),o(r,["setUserProfile","resetUserProfile","updateUserProfile"]);var p=t.createElement("script"),t=t.getElementsByTagName("script")[0];p.type="text/javascript",p.async=!0,p.src="https://cdn.pyze.com/pyze.js",t.parentNode.insertBefore(p,t),e.Pyze=s,e.PyzeEvents=i,e.PyzeCuratedEvents=n,e.PyzeIdentity=r}(window,document),Pyze.initialize(pyzeAppKey);
Replace YOUR_PYZE_APP_KEY with the Pyze App Key obtained from your growth.pyze.com account.
Warning
Make sure you replacedYOUR_PYZE_APP_KEY with your own appKey
Step 1: Choose where the library is loaded from
Pyze CDN
Choose this if user browsers can reach https://cdn.pyze.com and, if a CSP is in force, cdn.pyze.com can be allowed under script-src.
Use the loader as shown above. No other file is needed.
Self-hosted in Guidewire
Choose this for locked-down networks, or on Guidewire Cloud where the CSP is managed by Guidewire. The library is served from the application itself, so no external script domain is needed.
- Download the Pyze library from
https://cdn.pyze.com/pyze.jsand copy it tomodules/configuration/webresources/javascript/pyze.jsin your configuration module, so that the application serves it atjavascript/pyze.js. Do not edit it. - In the loader, replace
https://cdn.pyze.com/pyze.jswithjavascript/pyze.jsso the library is loaded from your application.
Do not also list pyze.js in Client_Header.json: the loader loads it, and listing it as well would load the library twice.
Step 2: Add the loader to the application shell
Check how your release adds client-side JavaScript to the application shell: a shared client JavaScript file (commonly customer.js), or the scripts listed in Client_Header.json. See the Guidewire documentation “Add JavaScript to the client application” for your release, or view the page source after login.
| If | Use |
|---|---|
The release adds a shared file or the Client_Header.json scripts to the shell |
Method 1 β Shared client JavaScript |
| Neither reaches the shell | Method 2 β TemplatePanel on a shell-level PCF |
| Method 2 does not work on your release | Method 3 β Servlet filter |
Use only one method; each of them loads the loader on its own.
Method 1: Shared client JavaScript
-
Either paste the entire contents of the loader into the shared file (e.g.
customer.js), or save the loader asmodules/configuration/webresources/javascript/pyze-loader.jsand add it to thescriptarray inClient_Header.json:{ "src": "javascript/pyze-loader.js" } -
Rebuild web resources and deploy.
-
After login, view the page source and confirm the file is referenced. If it is not, use Method 2.
Do not paste the loader into a single screen, widget, or popup β it would only load on that screen.
Method 2: TemplatePanel on a shell-level PCF
-
Create a Gosu template named
PyzeScript.gstthat emits the loader inside a<script>tag:<%@ template PyzeScript() %> <%-- Emits the Pyze loader. Referenced from a TemplatePanel on a shell-level PCF. --%> <script type="text/javascript"> // Paste the contents of the loader here </script> -
Copy
PyzeScript.gstinto the configuration module’s Gosu template location. -
Add a
TemplatePanelto a PCF that renders for every location after login β typically the tab bar or desktop-level shell PCF:<TemplatePanel id="PyzeScriptPanel" template="yourpackage.PyzeScript" /> -
Make sure this PCF appears in every workspace you use, not just one Center or tab β desktop PCFs differ between PolicyCenter, ClaimCenter and BillingCenter. Check Desktop, Search, and a wizard page.
-
Rebuild and deploy.
Method 3: Servlet filter
If you are on Guidewire Cloud, confirm with Guidewire that a custom servlet filter is permitted in your environment before using this method.
-
Save the loader as
modules/configuration/webresources/javascript/pyze-loader.js, so that the application serves it atjavascript/pyze-loader.js. Do not also list it inClient_Header.json: the filter adds the script tag. -
Add the following class to the configuration module’s compiled source tree (package
pyze, per your release’s project layout). Set itsTAGconstant to the path at which your application serves the loader. The class uses thejavax.servletAPI and needs Servlet 3.1 or later; on a release that uses thejakarta.servletAPI, change the twoimportlines.package pyze; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; /** * Adds the Pyze loader script tag before </head> in InsuranceSuite HTML pages. * Requires Servlet 3.1 or later (javax.servlet). Map it after any compression * filter in web.xml so that it sees the uncompressed HTML. */ public class PyzeScriptFilter implements Filter { // The path at which the application serves the loader. private static final String TAG = "<script src=\"javascript/pyze-loader.js\"></script>"; public void init(FilterConfig config) {} public void destroy() {} public void doFilter(ServletRequest rq, ServletResponse rs, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) rq; HttpServletResponse res = (HttpServletResponse) rs; if (!"GET".equals(req.getMethod())) { chain.doFilter(rq, rs); return; } BufferedResponse buffered = new BufferedResponse(res); chain.doFilter(req, buffered); byte[] body = buffered.getBytes(); String type = res.getContentType(); boolean html = type != null && type.toLowerCase().contains("text/html"); boolean encoded = res.getHeader("Content-Encoding") != null; if (html && !encoded) { String charset = res.getCharacterEncoding() != null ? res.getCharacterEncoding() : "UTF-8"; String page = new String(body, charset); int head = page.lastIndexOf("</head>"); if (head >= 0) { page = page.substring(0, head) + TAG + page.substring(head); body = page.getBytes(charset); } } // Anything else (downloads, compressed responses, non-HTML) is passed through untouched. res.setContentLength(body.length); res.getOutputStream().write(body); res.getOutputStream().flush(); } /** Holds the response body in memory so it can be inspected and modified. */ static class BufferedResponse extends HttpServletResponseWrapper { private final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); private ServletOutputStream stream; private PrintWriter writer; BufferedResponse(HttpServletResponse response) { super(response); } @Override public ServletOutputStream getOutputStream() { if (stream == null) { stream = new ServletOutputStream() { @Override public void write(int b) { buffer.write(b); } @Override public void write(byte[] b, int off, int len) { buffer.write(b, off, len); } @Override public boolean isReady() { return true; } @Override public void setWriteListener(WriteListener listener) {} }; } return stream; } @Override public PrintWriter getWriter() throws IOException { if (writer == null) { String charset = getCharacterEncoding() != null ? getCharacterEncoding() : "UTF-8"; writer = new PrintWriter(new OutputStreamWriter(buffer, charset)); } return writer; } // The length is set once the body has been modified. @Override public void setContentLength(int length) {} @Override public void setContentLengthLong(long length) {} // Keep everything in the buffer until the filter writes it out. @Override public void flushBuffer() {} byte[] getBytes() { if (writer != null) writer.flush(); return buffer.toByteArray(); } } } -
Register the filter in
config/web/WEB-INF/web.xmlafter any gzip or compression filter. Filters run in the order they are mapped, and the filter must receive the HTML before it is compressed:<filter> <filter-name>PyzeScriptFilter</filter-name> <filter-class>pyze.PyzeScriptFilter</filter-class> </filter> <filter-mapping> <filter-name>PyzeScriptFilter</filter-name> <url-pattern>*.do</url-pattern> </filter-mapping> -
Rebuild and deploy. On a development environment, confirm the page source shows the Pyze script tag before
</head>.
Notes
- On Guidewire Cloud, custom JavaScript is subject to Cloud Assurance review. Where it is not permitted, the Pyze browser extension captures the application without any change to it.
Verification
After deployment:
- Open the Guidewire application in a browser and log in.
- Open Developer Tools (Network and Console tabs).
- Confirm that the Pyze script loads without errors.
- Navigate through a few screens. You should see requests to
unifiedcollector.pyze.comreturning status 202. That confirms the SDK is loaded and sending events.
If there are no such requests, type Pyze in the Console. If it is undefined, the loader never ran β check the console for errors and see Troubleshooting below.
Troubleshooting (Classic PCF UI)
| Symptom | Likely cause | Action |
|---|---|---|
Pyze undefined |
Loader not on the shell page, or blocked | Check console errors; confirm the loader is in page source / DOM; try the next Step 2 method |
<script> in DOM but Pyze undefined (Method 2) |
Release strips inline template scripts | Use Method 3 (Servlet filter) |
Pyze gone after a wizard step or Center switch (Method 2) |
Shell PCF is not global | Change the PCF, or use Method 1 (Shared client JavaScript file) or Method 3 (Servlet filter) |
Pyze defined but no events (Pyze CDN) |
cdn.pyze.com blocked by network or CSP |
Allow-list it, or switch to self-hosting |
No requests to unifiedcollector.pyze.com |
Blocked by network or CSP connect-src |
Allow-list unifiedcollector.pyze.com |
| Script tag missing from source (Method 3) | Filter not registered, or mapped before the compression filter | Check the order in web.xml |
| Loader file 404 (Method 3) | Loader not under webresources/javascript/, or the served path differs on this release |
Check the file location; adjust TAG |
pyze.js 404 (Self-hosted) |
File not under webresources/javascript/, or the served path differs on this release |
Check the file location; adjust the path in the loader |
| Library initialized twice, or duplicate events | The loader and pyze.js are both loaded by two methods at once |
Use one method only; remove the extra Client_Header.json entry or script tag |