Best Practices for deploying JasperReports Server into your web application

This article will outline options to integrate TIBCO JasperReports® Server into your web application architecture, focusing on arrangements of:

  • Browser: loading and executing HTML, Javascript and REST (Ajax) requests
  • Your web application server: serving content to the browser
  • Proxy or Load balancer
  • HTTP and HTTPS traffic
  • TIBCO JasperReports Server instance(s)

Visualize.js is a powerful and simple way to embed JasperReports Server visualizations and metadata into your web application user interface.

Loading visualize.js into your browser

Loading from a JasperReports Server

In your application web page, load the visualize.js API into the browser directly from a JasperReports Server instance. This is the approach in the visualize.js documentation. Requesting the visualize.js script

<script src=""></script>

The JasperReports Server instance URL has to be accessible from where the browser is. This could be a URL to a proxy or load balancer which are configured to route traffic to JasperReports Server instances. You could have a proxy to JasperReports Server within your web application, like:

<script src="/jasperserver-pro/client/visualize.js"></script>

See the Proxy defintions for JasperReports Server section for details.

When you load visualize.js from a JasperReports Server instance like this, you are actually hitting a JasperReports Server servlet that dynamically generates Javascript and configuration content that is executed by the browser.

Loading from your application

Instead of loading visualize.js from a JasperReports®Server instance, you can also extract the visualize.js Javascript library from the JasperReports Server, put it into your own web application and load it from there. As of version 6.4, the library you want is in:

<JRS web app deployment directory>/optimized-scripts/client/visualize.js

You would load this like any other Javascript library.

<script src="myJavascript/jaspersoft/visualize.js"></script>

This is a 1.9 MB file that has been minimized. The self contained library cannot be included into your application via Javascript compilation with webpack or Typescript.

Loading the visualize API results in the creation of:

  • visualize global variable
  • themeHref global variable: only if visualize is loaded directly from a JasperReports Server instance

visualize does load parts of a JasperReports Server theme dynamically, to be used within interactive report controls. Theme documentation

You can also put the JasperReports Server theme(s) in your web application as opposed to pulling them dynamically from JasperReports Server. Download JasperReports Server theme zips from the JasperReports Server and unzip them in your web application under something like "css/jasper/<themeName>". You can update the theme CSS and graphics and create new themes within your app. Each theme will require the full set of files of a theme, not just the override.css as happens within JasperReports Server.

Version 6.4 issue: In testing this approach of including the visualize.js library in your web app, I have found that the visualize.js dashboard API does not load themes properly, causing the dashboards to be distorted. If you want to use the dashboard API, you must load visualize.js from the JasperReports Server, as describe previously.

<script src="

Initializing visualize.js

With the visualize.js API loaded, you can then call visualize in Javascript to:

  • authenticate against a JasperReports Server instance
  • get a session cookie from the JasperReports Server instance to be stored in the browser
    • allows authentication in one page to be available in other pages
  • get a visualize reference object that implements the API and communicates with the JasperReports Server instance

Use this form of call if the visualize API was loaded directly from a JasperReports Server instance with no proxy ie.

    auth: {
        name: "joeuser",
        password: "joeuser",
        organization: "organization_1"
}, function (v) {
    // save the v reference object for later use

If visualize was loaded via a proxy or from your web app:

// application proxy
var jrsUrl = "/jasperserver-pro";
// or a full URL
//var jrsUrl = "";
// themeHref is a global variable created by loading visualize from a JRS instance
// initially, it is something like: http://localhost:8080/jasperserver-pro/_themes/19BF127D
if (typeof themeHref !== 'undefined') {
    // JRS runs on a URL like http[s]://[:8080]/jasperserver-pro
    // The JRS URL points to http[s]://[:9999]/jasperserver-pro
    // or a relative /jasperserver-pro 
    var jrsPathToFind = "/jasperserver-pro";
    var posOfRelative = themeHref.indexOf(jrsPathToFind);
    if (posOfRelative > 0) {
        themeHref = jrsUrl + themeHref.substring(posOfRelative + jrsPathToFind.length);
} else {
    // app served visualize.js script
    // point to themes installed in web app
    themeHref = "css/jasper/default";
    // if you want to use the JRS served themes, remove theme part of the object below.
// transformed themeHref
console.log("themeHref: " + themeHref);
    // always set this, even if it is the same as the URL where you loaded the visualize.js in the script tag
    baseUrl: jrsUrl,
    server: jrsUrl,
    scripts: "optimized-scripts",
    theme: {
        href: themeHref
    auth: {
        name: "joeuser",
        password: "joeuser",
        organization: "organization_1"
    // You can set the properties that are documented for the visualize.js script load here too
    userLocale: "en_US"
}, function (v) {
    // save the v reference object for later use

Proxy definitions for JasperReports Server

The documentation on proxying Jaspersoft is here: Configuration for Using Proxies

The advice to use the deploy.base.url setting within the JasperReports Server instance is actually only useful in the simplest use case, where all web apps refer to the JasperReports Server instance or load balancer with the same URL and proxies etc never change. In practice, deploy.base.url should not be set at all. Using the configurations outlined in this article removes the need to set deploy.base.url.

Clustering and Load Balancing JasperReports Server Ultimate Guide: Designing a Cluster

The proxy definition to route traffic to JasperReports Server is simple but restricted. The configuration below is relevant for load balancers, which are, in essence, proxies.

Apache proxy definition example

ProxyPass /jasperserver-pro http://internalDomain:8080/jasperserver-pro

Due to JasperReports Server's generation of URLs in its content, the proxy URL "/jasperserver-pro" must match the path on the target JasperReports Server instance.

# These will not work: proxy path does not match JasperReports Server path
ProxyPass /jasper http://internalDomain:8080/jasperserver-pro
ProxyPass /myApp/jasperserver-pro http://internalDomain:8080/jasperserver-pro

Proxies can cause CSRF issues with JasperReports Server, depending on domain names being used. See CSRF Guard Javascript fix

URL Rewriting

There are some parts of the JasperReports Server user interface that generate full URLs in JSON to the browser ("hypermedia" REST responses). These URLs can be incorrect when proxies are used. Evidence of this is the JasperReports Server Home Page missing icons and other content.

To fix this:

For JasperReports Server versions 7.1.X and later

JasperReports Server 7.1 added a filter to use HTTP headers to help with proxy configuration. Combined with the proxy configurations like ProxyPass outlined above, setting these headers will force JasperReports Server to generate the hypermedia URLs with the correct scheme and port (if needed).

For Apache

RequestHeader set X-Forwarded-Proto "https"
# X-Forwarded-Port only needs to be set of the proxy server uses non standard ports
RequestHeader set X-Forwarded-Port "444"

For JasperReports Server versions 6.4.X and previous

You need to rewrite the JSON content to remove the scheme, domain and port from the URLs. In Apache, you can do this via mod_substitute:

  # Update rest_v2/hypermedia responses
  <Location "/jasperserver-pro/rest_v2/hypermedia">
       AddOutputFilterByType SUBSTITUTE application/hal+json
       Substitute "s|http://<JRS domain>:<JRS port>/|/|inq"

In some cases, the <JRS domain>:<JRS port> above will be your proxy server.