How to integrate JSF 2.3 with bootstrap-sass, FontAwesome, browser-sync and gulp ?

This post is based on the excellent article from and the following answer in stackOverflow.

The problem

The relative paths used in the URLs of the bootstrap's glyphicons are broken when bootstrap is used with JSF.
In standard, the format of the path is as following:
but the format required by JSF is as following:

The idea is to build bootstrap with sass and modify consequently the path.

The solution

1. Install npm, bower and gulp

- npm init
- npm install bower --saved-dev
- npm install gulp --saved-dev
- npm install gulp-sass --saved-dev
- npm install gulp-cssnano --saved-dev

2. Install bootstrap-sass, FontAwesome and browser-sync

  • npm install browser-sync --saved-dev
  • bower install bootstrap-sass --saved-dev
  • bower install components-font-awesome --saved-dev

3. The gulp script

To have the full explanation of this part, report to the following article in

We suppose here that all the scss files for customization are in src/main/view/.

var gulp        = require('gulp');  
var browserSync = require('browser-sync').create();  
var sass        = require('gulp-sass');  
var cssnano     = require('gulp-cssnano');

//source and distribution folder
    source = 'src/main/view/',
    dest = 'src/main/webapp/resources/dist/';

// Bootstrap scss source
var bootstrapSass = {  
        in: './bower_components/bootstrap-sass/'

// Font-Awesome scss sources
var fontAwesomeSass = {  
        in: './bower_components/components-font-awesome/'

var jqueryScripts = {  
        in: './bower_components/jquery/'

// Bootstrap fonts source
var fonts = {  
        in: [source + 'fonts/*.*', + 'assets/fonts/**/*', + 'fonts/**/*'],
        out: dest + 'fonts/'

var bootstrapJS = {  
        in: ['dist/**/*', + 'assets/javascripts/**/*'],
        out: dest + 'js/'

// Our scss source folder: .scss files
var scss = {  
    in: source + 'scss/main.scss',
    out: dest + 'css/',
    watch: source + 'scss/**/*',
    sassOpts: {
        outputStyle: 'nested',
        precison: 3,
        errLogToConsole: true,
        includePaths: ['scss', + 'assets/stylesheets']

// Bootstrap javascripts
gulp.task('bootstrap_js', function () {  
    return gulp

//copy bootstrap required fonts to dest
gulp.task('fonts', function () {  
    return gulp

//compile scss
gulp.task('sass', ['fonts', 'bootstrap_js'], function () {  
    return gulp.src(

gulp.task('dist', ['fonts', 'bootstrap_js'], function () {  
    return gulp.src(

//default task
gulp.task('default', ['sass'], function () {  
        proxy: "localhost:8080"
    });, ['sass']);"src/main/webapp/**/*.xhtml").on('change', browserSync.reload);

4. The sass' files

In the directory src/main/view/ (source directory in the gulp file), the following custom sass' files:

  • The file _bootstrap-custom.scss:
 * Bootstrap v3.3.7 (
 * Copyright 2011-2016 Twitter, Inc.
 * Licensed under MIT (

@function twbs-font-path($path) {
     @return "\#{resource['dist:#{$path}']}";

@function twbs-image-path($path) {
      @return $path;

$bootstrap-sass-asset-helper: true;

// Core variables and mixins
@import "bootstrap/variables";
@import "bootstrap/mixins";

// Reset and dependencies
@import "bootstrap/normalize";
@import "bootstrap/print";
@import "bootstrap/glyphicons";

// Core CSS
@import "bootstrap/scaffolding";
@import "bootstrap/type";
@import "bootstrap/code";
@import "bootstrap/grid";
@import "bootstrap/tables";
@import "bootstrap/forms";
@import "bootstrap/buttons";

// Components
@import "bootstrap/component-animations";
@import "bootstrap/dropdowns";
@import "bootstrap/button-groups";
@import "bootstrap/input-groups";
@import "bootstrap/navs";
@import "bootstrap/navbar";
@import "bootstrap/breadcrumbs";
@import "bootstrap/pagination";
@import "bootstrap/pager";
@import "bootstrap/labels";
@import "bootstrap/badges";
@import "bootstrap/jumbotron";
@import "bootstrap/thumbnails";
@import "bootstrap/alerts";
@import "bootstrap/progress-bars";
@import "bootstrap/media";
@import "bootstrap/list-group";
@import "bootstrap/panels";
@import "bootstrap/responsive-embed";
@import "bootstrap/wells";
@import "bootstrap/close";

// Components w/ JavaScript
@import "bootstrap/modals";
@import "bootstrap/tooltip";
@import "bootstrap/popovers";
@import "bootstrap/carousel";

// Utility classes
@import "bootstrap/utilities";
@import "bootstrap/responsive-utilities";
  • The file _bootstrap-override-variables.scss:
<copy of bower_components/bootstrap-sass/assets/stylesheets/bootstrap/_variables.scss file>  

bootstrap can be customized in this file.

  • The file _font-awesome-custom.scss:
 *  Font Awesome 4.7.0 by @davegandy - - @fontawesome
 *  License - (Font: SIL OFL 1.1, CSS: MIT License)

@function resource_url($url,$params) { 
    @return url + "(\"\#{resource['dist:#{$url}']}&#{$params}\")";

@import "variables";
@import "mixins";
@import "font-awesome-path-custom";
@import "core";
@import "larger";
@import "fixed-width";
@import "list";
@import "bordered-pulled";
@import "animated";
@import "rotated-flipped";
@import "stacked";
@import "icons";
@import "screen-reader";
  • The file _font-awesome-override-variables.scss:
// Variables
// --------------------------

$fa-font-path:        "/fonts" !default;
<+ rest of file bower_components/components-font-awesome/scss/_variables.scss >  
  • and the file main.scss:
/* main.scss */
@import "bootstrap-override-variables";

@import "bootstrap-custom";
@import "bootstrap/theme";

/* import font-awesome */
@import "font-awesome-override-variables";

@import "font-awesome-custom";

Sébastien Attia

My core skill sets are Software Engineering and Machine Learning. One of my greatest strengths is my ability to analyse a problem, break it down in parts and understand those parts.

Geneva, Switzerland

Subscribe to's notes by Sébastien Attia

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!