I know there are some outdate and deprecated / no more supported projects like GWT-Bootstrap (https://github.com/gwtbootstrap/gwt-bootstrap) and gwtbootstrap3 (https://github.com/gwtbootstrap3/gwtbootstrap3) who integrate the Bootstrap library into GWT projects, however I know it's possible to use standard javascript Bootstrap library (https://getbootstrap.com/) into a modern GWT App (for modern I mean 'at the ages of 2025' using for example the Thomas Broyer Maven artifact). I know for example it should be possible to include it as a Maven dependency this way:
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>5.3.7</version>
</dependency>
The question is: is there a guide, a tutorial, some documentation or an article online or could someone explain how to use it with a demonstration?
You can use the modern standard way to integrate Bootstrap as a third-party JS-library into your GWT application.
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>5.3.7</version>
</dependency>
Use WebJar locator or manually reference.
<link rel="stylesheet" href="webjars/bootstrap/5.3.7/css/bootstrap.min.css" />
<script src="webjars/bootstrap/5.3.7/js/bootstrap.bundle.min.js"></script>
For Bootstrap's JS-driven components (modals, dropdowns, tooltips), you’ll need to initialize them manually via JSNI or JsInterop calls, as GWT widgets do not automatically handle Bootstrap's data attributes like data-bs-toggle.
@JsMethod(namespace = "bootstrap")
public static native void Modal(Element element);
public void initModal(Element modalElement) {
Modal(modalElement);
}
@JsType(isNative = true, namespace = "bootstrap", name = "Modal")
public class Modal {
public Modal(Element element) {}
public void show() {}
public void hide() {}
}
Element modalEl = Document.get().getElementById("myModal");
Modal modal = new Modal(modalEl);
modal.show();
myWidget.getElement().setAttribute("data-bs-toggle", "dropdown");
Or create custom widgets that expose setters for these attributes.
<g:HTMLPanel>
<g:Button ui:field="showModalButton" styleName="btn btn-primary">
Launch demo modal
</g:Button>
<div class="modal fade" ui:field="myModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
This is a Bootstrap 5 modal controlled by GWT and JsInterop!
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</g:HTMLPanel>
</ui:UiBinder>
import elemental2.dom.HTMLDivElement;
import jsinterop.base.Js;
public class MyView extends Composite {
interface MyViewUiBinder extends UiBinder<Widget, MyView> {}
private static MyViewUiBinder uiBinder = GWT.create(MyViewUiBinder.class);
@UiField
Button showModalButton;
@UiField
HTMLDivElement myModal;
private BootstrapModal modal;
public MyView() {
initWidget(uiBinder.createAndBindUi(this));
}
@Override
protected void onAttach() {
super.onAttach();
ModalOptions options = ModalOptions.create(true, "static", true);
this.modal = new BootstrapModal(myModal, options);
myModal.addEventListener("shown.bs.modal", evt -> {
GWT.log("Modal was shown");
});
myModal.addEventListener("hidden.bs.modal", evt -> {
GWT.log("Modal was hidden");
});
}
@Override
protected void onDetach() {
super.onDetach();
if (this.modal != null) {
this.modal.dispose();
}
}
@UiHandler("showModalButton")
void onShowModalClick(com.google.gwt.event.dom.client.ClickEvent e) {
if (this.modal != null) {
this.modal.show();
}
}
}