Modifying the bootstrap page
- Viewport annotation
- Inline annotation
- PageConfigurator
- Setting the body size styles
- BootstrapListener
- Adding static HTML contents
The application bootstrap page is created for you by the framework and normally there is no need to modify it.
For instance Flow includes its internal JavaScripts to be able to provide its core functionality.
Also it is possible to include additional JavaScripts, HTML imports and Style Sheets using annotations @JavaScript,
@CssImport and @StyleSheet (see Importing Style Sheets and Importing JavaScript).
Sometimes you may want to customize the page header and add there some additional data, e.g. custom meta tags.
Such markup is required to enable your web page to become a rich object in a social graph using OpenGraph protocol.
Viewport annotation
Viewport meta-tag can be set to the initial page by annotating the navigation target with @Route or
the top most RouterLayout that builds the navigation target chain.
Source code
Java
@Route("")
@Viewport("width=device-width")
public class MyApp extends Div {
public MyApp() {
setText("Hello world");
}
}Source code
Java
@Route(value = "", layout = MyLayout.class)
public class MyView extends Div {
public MyView() {
setText("Hello world");
}
}
@Viewport("width=device-width")
public class MyLayout extends Div implements RouterLayout {
}|
Note
|
If the Viewport annotation is not on a `@Route Component or a top RouterLayout an exception will be thrown on startup.
|
Inline annotation
The initial page can be modified by using the @Inline annotations to add file contents
to either the <head> or the <body>. Inline is repeatable, so multiple @Inline annotations
can be added at once.
Inline will add the contents of a classloader resource by default as appended to the head of the initial page with type decided by the file suffix.
The configurations available for inlining contents are:
-
TargetElement [HEAD, BODY]
-
Position [APPEND, PREPEND]
-
Wrapping [AUTOMATIC, NONE, STYLESHEET, JAVASCRIPT]
Source code
Java
@Route(value = "", layout = MyInline.class)
public class MyRoot extends Div {
public MyRoot() {
}
}
@Inline("initialization.js")
@Inline("initial_style.css")
@Inline(value = "important_styles", wrapping = Inline.Wrapping.STYLESHEET)
public class MyInline extends Div implements RouterLayout {
}|
Note
|
If the Inline annotation is not on a @Route Component or a top RouterLayout an exception will be thrown on startup.
|
PageConfigurator
To be able to modify default bootstrap page and add your custom meta tags on the page you
can implement the PageConfigurator on the navigation target with @Route or
the top most RouterLayout that builds the navigation target chain. The PageConfigurator gives
you easy access to customize the LoadingIndicatorConfiguration, ReconnectDialogConfiguration and
PushConfiguration for the initial response.
With the PageConfigurator you can prepend or append javascript, html and css to the head
by giving a file on the classpath or as content string. Also supported is adding links and meta tags which
can also be either prepended or appended.
Setting the viewport meta tag using InitialPageSettings::setViewport will override any viewport
set through a @Viewport annotation.
By default everything is appended, but if needed you can give the position InitialPageSettings.Position.PREPEND
to have the item prepended to head instead.
Here is the code for the PageConfigurator implementation on the top
RouterLayout which modifies the header of the page:
Source code
Java
@Route(value = "", layout = MainLayout.class)
public class Root extends Div {
}
public class MainLayout extends Div
implements RouterLayout, PageConfigurator {
@Override
public void configurePage(InitialPageSettings settings) {
settings.addInlineFromFile(InitialPageSettings.Position.PREPEND,
"inline.js", InitialPageSettings.WrapMode.JAVASCRIPT);
settings.addMetaTag("og:title", "The Rock");
settings.addMetaTag("og:type", "video.movie");
settings.addMetaTag("og:url",
"https://www.imdb.com/title/tt0117500/");
settings.addMetaTag("og:image",
"https://ia.media-imdb.com/images/rock.jpg");
settings.addLink("shortcut icon", "icons/favicon.ico");
settings.addFavIcon("icon", "icons/icon-192.png", "192x192");
}
}|
Note
|
If the PageConfigurator implementation is not on a @Route Component or a RouterLayout used from a route it will not be used.
|
Setting the body size styles
By default, the body element in a Flow application has size properties height = "100vh", width = "100vw",
which makes the page fill the entire viewport.
To change the width and height properties of the body you can either use the @BodySize annotation or the PageConfigurator.
For @BodySize you just add it to the the navigation target with @Route or
the top most RouterLayout that builds the navigation target chain.
You can pass custom height and width properties for the annotation, or leave them out
to just prevent the default size to be applied for the body:
Source code
Java
@Route("")
@BodySize
public static class BodySizeAnnotatedRoute extends Div {
}With the PageConfigurator you can just addInlineContent like:
Source code
Java
@Route("")
public static class InitialPageConfiguratorBodyStyle extends Div
implements PageConfigurator {
@Override
public void configurePage(InitialPageSettings settings) {
settings.addInlineWithContents("body {width: 100vw; height:100vh;}",
InitialPageSettings.WrapMode.STYLESHEET);
}
}|
Note
|
Only one way should be used as else the later statement will override the earlier one. In practise this would
mean that by default the PageConfigurator will override the @BodySize except if the inlining is done as
a PREPEND then the @BodySize will be the deciding one.
|
|
Note
|
If the BodySize annotation is not on a @Route Component or a top RouterLayout an exception will be thrown on startup.
|
|
Note
|
When using an empty @BodySize annotation (which doesn’t apply any sizing for the UI / body), you will not be able to use relative sizing (% as unit) for any component, unless the component has a parent that has defined size using anything else than % as the unit. For that reason, it is recommended to use the default settings for the body size, by omitting the @BodySize annotation, or to declare a specific size for it.
|
BootstrapListener
To be able to modify default bootstrap page and add your custom meta tags on the page you should use
your BootstrapListener implementation and add it to the ServiceInitEvent instance available
in a VaadinServiceInitListener.
Here is the code for the BoostrapListener implementation which modifies the header of the page:
Source code
Java
public class CustomBootstrapListener implements BootstrapListener {
public void modifyBootstrapPage(BootstrapPageResponse response) {
Document document = response.getDocument();
Element head = document.head();
head.appendChild(createMeta(document, "og:title", "The Rock"));
head.appendChild(createMeta(document, "og:type", "video.movie"));
head.appendChild(createMeta(document, "og:url",
"https://www.imdb.com/title/tt0117500/"));
head.appendChild(createMeta(document, "og:image",
"https://ia.media-imdb.com/images/rock.jpg"));
}
private Element createMeta(Document document, String property,
String content) {
Element meta = document.createElement("meta");
meta.attr("property", property);
meta.attr("content", content);
return meta;
}
}Now this listener should be added to a ServiceInitEvent which is sent when a Vaadin service is initialized. Take a look on the ServiceInitListener tutorial on how to configure it.
Adding static HTML contents
The framework provides multiple ways of adding static content to the page. Here we cover three different ways of adding a favicon.
-
using
InitialPageSettings#addLink()
Source code
Java
public class Layout1 extends Div implements RouterLayout, PageConfigurator {
@Override
public void configurePage(InitialPageSettings settings) {
HashMap<String, String> attributes = new HashMap<>();
attributes.put("rel", "shortcut icon");
settings.addLink("icons/favicon.ico", attributes);
}
}-
using
InitialPageSettings#addInlineWithContents()
Source code
Java
public class Layout2 extends Div implements RouterLayout, PageConfigurator {
@Override
public void configurePage(InitialPageSettings settings) {
settings.addInlineWithContents(
"<link rel=\"shortcut icon\" href=\"icons/favicon.ico\">",
InitialPageSettings.WrapMode.NONE);
}
}-
using
BootstrapListener#modifyBootstrapPage()(documentation)
Source code
Java
public class Layout3 extends Div
implements RouterLayout, BootstrapListener {
@Override
public void modifyBootstrapPage(BootstrapPageResponse response) {
final Element head = response.getDocument().head();
head.append(
"<link rel=\"shortcut icon\" href=\"icons/favicon.ico\">");
}
}But most commonly, you will deal with quite many files, in this case, you can see that it causes a lot of hard coding easily. To avoid this, we recommend you to move all the contents into a file, (e.g. your-content.html) and inline this file in your PageConfigurator
Source code
Java
public class Layout4 extends Div implements RouterLayout, PageConfigurator {
@Override
public void configurePage(InitialPageSettings settings) {
settings.addInlineFromFile("your-content.html",
InitialPageSettings.WrapMode.NONE);
}
}7B97DE3E-DE54-4C2D-81F4-976965D96337