This page looks best with JavaScript enabled

Django Bootstrap using WebPack

 ·  🎃 kr0m

Bootstrap is a well-known web development framework for frontend, which includes CSS style sheets and JS libraries that will make programming much easier for us. In this article, we will explain how to use Bootstrap within a Django/Webpack project.

Before we begin, it is recommended to read the previous articles on Django as they are the previous steps to this article:


We install Bootstrap and its dependencies:

yarn add bootstrap jquery popper.js

With webpack, the variables within our JS code are no longer global, which presents some problems in certain obsolete libraries. To solve these problems, we must define some variables. The best place to do this is in the minimal.js file since the templates will extend from minimal.html.

We should not define these variables in several files or import Bootstrap in several points of the code since it will cause problems and anomalous behaviors. Some Bootstrap functionalities will fail without showing any type of error.

Our code will look like this:

vi assets/js/minimal.js

// JQuery stuff
import $ from 'jquery';
global.$ = global.jQuery = $;

import 'bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';

console.log('Inside minimal. Edit me in assets/js/minimal.js');
vi assets/js/base.js
console.log('Inside base. Edit me in assets/js/base.js');

On the index page, we will add some debug through the browser’s JS console to verify that Bootstrap was successfully loaded and we will also display the version of JQuery:

vi assets/js/index.js
import img from '../images/django-logo-positive.png';

// ------ OnLoad checks ------
window.onload = function() {
    // Basic checks
    console.log('----- window.onload -----');
    if (typeof $.fn.popover == 'function') { 
        console.log('BootStrap working correctly');
    } else {
        console.log('BootStrap NOT working correctly');
    }

    if (typeof jQuery != 'undefined') {  
        // jQuery is loaded => print the version
        console.log('JQuery version: ' + jQuery.fn.jquery);
    }
};

console.log('Inside index. Edit me in assets/js/index.js');

We register the new entry points:

vi webpack.ENV.config.js
var path = require("path")
var webpack = require('webpack')
var BundleTracker = require('webpack-bundle-tracker')
var ProgressBarPlugin = require('progress-bar-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    mode: "development",
    context: __dirname,
    entry: {
        minimal: './assets/js/minimal.js',
        base: './assets/js/base.js',
        index: './assets/js/index.js',
    },

    output: {
        path: path.resolve('./assets/bundles/'),
        publicPath: '/static/',
        filename: "[name]-[fullhash].js",
    },

    plugins: [
        new BundleTracker({filename: '../../webpack-stats.json'}),
        new ProgressBarPlugin(),
        new MiniCssExtractPlugin({
            filename: '[name]-[hash].css',
        }),
    ],

    module:{
        rules:[
            {
                test: /\.css$/i,
                use: [MiniCssExtractPlugin.loader, 'css-loader'],
            },
            {
                test: /\.(png|jpe?g|gif)$/i,
                loader: 'file-loader',
                options: {
                  name: '[name].[ext]',
                },
            },
       ]
    },
}

We modify the templates to make use of some Bootstrap element, such as a card:

vi rxWod/templates/rxWod/minimal.html
{% load render_bundle from webpack_loader %}

<!doctype html>
<html lang="en">
    <head>
        <!-- Required meta tags for BootStrap -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <title>rxWod</title>
        {% render_bundle 'minimal' 'css'%}
        {% block minimal_head %}
        {% endblock %}
    </head>
    <body>
        <p>Minimal Template</p>
        {% render_bundle 'minimal' 'js'%}
        {% block minimal_body %}
        {% endblock %}
    </body>
</html>
vi rxWod/templates/rxWod/base.html
{% extends 'rxWod/minimal.html' %}
{% load render_bundle from webpack_loader %}

{% block minimal_head %}
    {% render_bundle 'base' 'css'%}
    {% block base_head %}
    {% endblock %}
{% endblock %}

{% block minimal_body %}
    <p>Base template</p>
    {% render_bundle 'base' 'js'%}
    {% block base_body %}
    {% endblock %}
{% endblock %}
vi rxWod/templates/rxWod/index.html
{% extends 'rxWod/base.html' %}
{% load render_bundle from webpack_loader %}
{% load webpack_static from webpack_loader %}

{% block base_head %}
    {% render_bundle 'index' 'css'%}
{% endblock %}

{% block base_body %}
        {% if routines %}
            {% for routine in routines %}
                <div class="col-xs-12 col-sm-12 col-md-6 col-lg-3 p-2 mb-2">
                    <div class="card text-center text-white bg-dark border border-primary rounded">
                        <div class="card text-center text-white bg-dark border border-primary rounded">
                            <div class="card-header">
                            <img class="text-center" src="{% webpack_static 'django-logo-positive.png' %}" width="150" height="90" alt="rxWod">
                        </div>
                        <div class="card-body">
                            <h5 class="card-title">{{ routine.date }}</h5>
                        </div>
                    </div>
                </div>
            {% endfor %}
        {% else %}
            <p>No routines available.</p>
        {% endif %}

    {% render_bundle 'index' 'js'%}
{% endblock %}

We recompile the bundles:

yarn dev-build

We access the website and see that Bootstrap is working:

In addition, in the browser’s JS console, we can verify that Bootstrap has been loaded correctly and check the version of JQuery (we can ignore the warnings about the .map files):

If you liked the article, you can treat me to a RedBull here