WebJars Now on the jsDelivr CDN

WebJars were created to work well with Content Deliver Networks (CDNs) and now thanks to jsDelivr there is a great public CDN hosting all of the WebJar assets! jsDelivr is “a free super-fast CDN for developers and webmasters.” What a perfect match for WebJars!

Here is how it works… Just prefix //cdn.jsdelivr.net in front of your WebJar asset URLs. That’s it! For instance, if the URL you setup to jquery.js is /webjars/jquery/2.1.0/jquery.js then to use the jsDelivr CDN the URL would be: //cdn.jsdelivr.net/webjars/jquery/2.1.0/jquery.js

Because I’m on planes a lot and sometimes have flaky internet, I still like to use my local WebJar assets when doing development. But when I’m running in production I want to switch my apps to pull the WebJar assets from the CDN. Luckily this is now really easy to setup. Here is how you would do it with Play Framework.

Step 1) Create a new controller in controllers/StaticWebJarAssets.scala containing:

package controllers
 
import play.api.mvc.Controller
import play.api.Play
import play.api.Play.current
 
object StaticWebJarAssets extends Controller {
 
  def at(file: String) = Assets.at("/META-INF/resources/webjars", file)
 
  def getUrl(file: String) = {
    val maybeContentUrl = Play.configuration.getString("contentUrl")
 
    maybeContentUrl.map { contentUrl =>
        contentUrl + controllers.routes.StaticWebJarAssets.at(file).url
    } getOrElse controllers.routes.StaticWebJarAssets.at(file).url
  }
 
}

This wrapper around Play’s Assets controller enables setting a contentUrl config parameter that turns the CDN on and off for this app.

Step 2) Update the conf/routes file to use this new controller for WebJar requests:

GET     /webjars/*file                    controllers.StaticWebJarAssets.at(file)

Step 3) Change the server-side templates to use the new StaticWebJarAssets.getUrl reverse routing wrapper so that the URLs in a page change based on the configuration. For example:

<link rel='stylesheet' href='@StaticWebJarAssets.getUrl(WebJarAssets.locate("css/bootstrap.min.css"))'>
<script type='text/javascript' src='@StaticWebJarAssets.getUrl(WebJarAssets.locate("jquery.min.js"))'></script>

Step 4) In the conf/application.conf file set the contentUrl config parameter, like:

contentUrl="//cdn.jsdelivr.net"

This will make your local development environment use the CDN. Instead you can just set this in your production config. The webjars.org site uses the following config:

contentUrl=${?CONTENT_URL}

This syntax sets the contentUrl config if a CONTENT_URL environment variable is present, otherwise it does not set it.

That is all I had to do to move the static asset handling for webjars.org to the jsDelivr CDN! Pretty awesome stuff.

A big huge thank you to jsDelivr and Dmitriy Akulov (who works for MaxCDN) for stepping up to help out WebJars!!! I emailed Dmitriy out-of-the-blue not expecting that they’d would be interested in helping WebJars but he quickly responded and helped me get everything setup in a matter of hours! With that kind of service I’m definitely looking into the MaxCDN services for my non-open source projects.