> Markdown version of [Storing and Loading Resources](https://vaadin.com/docs/v14/flow/importing-dependencies/tutorial-ways-of-importing). Section index: [llms.txt](https://vaadin.com/docs/v14/flow/llms.txt)

# Storing and Loading Resources

## <a id="storing-resources"></a>Storing Resources

### <a id="static-frontend-resources-for-webpack-bundling-14-npm-mode"></a>Static frontend resources for Webpack bundling (14 npm mode)

In Vaadin 14, static resources that are bundled using Webpack and referenced via `@JavaScript`, `@JsModule`, and `CssImport` annotations should be placed under `{project directory}/frontend`. This includes normal JavaScript files, Polymer 3 template files, and CSS files. When importing files using these annotations, prefix the path with `./`, which signifies the `frontend/` directory. For example, a CSS file `my-custom.css` under `{project directory}/frontend/styles/my-custom.css` would be referenced `@CssImport("./styles/my-custom.css")`.

If the `./` prefix is missing from a `@JsModule` annotation, the import is treated as a reference to an npm module under `node_modules/` folder.

### <a id="static-resources"></a>Static resources

> **Note:** Compatibility Mode and HTML imports are no longer supported from Vaadin 14.12 onwards.

This section covers static resource locations when in either compatibility mode or using resources that should not be bundled by Webpack.

You can place your resource files (CSS style sheets, JavaScript and HTML files, and other static resources) in any folder in your WAR file, except `/VAADIN`, which is reserved for internal framework use.

`VaadinServlet` handles static resource requests, if you have mapped it to `/*`. If not, the servlet container takes care of static resource requests.

If you use relative URLs, it is irrelevant whether your application is deployed in the root context (for example `https://mysite.com/`) or in a sub context (for example `https://mysite.com/myapp/`). Relative URLs are resolved using the page base URI, which is always set to match the servlet URL.

### <a id="using-a-servlet-path"></a>Using a Servlet Path

If you use a servlet path for the servlet, for example `https://mysite.com/myapp/myservlet/`, you need to take the servlet path into account when including resources. This is because the base URI is `https://mysite.com/myapp/myservlet/`, but static resources are deployed at `https://mysite.com/myapp/`.

You can use the `context://` protocol, with the `Page.addStyleSheet` method, for example. This ensures the URL is relative to the context path. This protocol is only supported when including resources.

When you configure an element, for example setting the `src` attribute for an `<img>`, you cannot use the `context://` protocol. Your options are:

- Take the servlet path into account with your relative URL, for example `../images/logo.png`.

- Use an absolute URL, for example `/myapp/images/logo.png`.

- Deploy your static resources in a directory that matches your servlet path, for example `/myservlet/`.

## <a id="advanced-configuration-of-css-javascript-and-html-imports"></a>Advanced configuration of CSS, JavaScript and HTML imports

As discussed in [Importing Style Sheets](https://vaadin.com/docs/v14/flow/styling/importing-style-sheets.md) and [Importing JavaScript](https://vaadin.com/docs/v14/flow/importing-dependencies/tutorial-importing.md), you can import client-side dependencies or resource files using:

- Annotations (`@JavaScript`, `@JsModule`, `@CssImport`, `@StyleSheet`, and `@HtmlImport`), and

- Methods provided by the `Page` class (`addJavaScript`, `addJsModule`, `addStyleSheet`, and `addHtmlImport`).

> **Note:** `@HtmlImport` and `addHtmlImport` work only in compatibility mode and while `@StyleSheet` does work as before, `@CssImport` may be a better fit.

Sometimes the way client-side resources are loaded to the browser affects the functionality of the application. Vaadin Flow provides advanced methods to configure the loading of these resources.

### <a id="dependency-loading-order"></a>Dependency Loading Order

Imported dependency files of the same type, load in the order they are defined in the class. For example, CSS files load in the `@CssImport` annotation definition order, JavaScript files in the `@JsModule` and `@JavaScript` annotation definition order.

The loading order of imported dependencies is only guaranteed for one file type, in one class. Specifically, loading order is not guaranteed between classes; annotations on class `A` could be imported before or after annotations on class `B`.

Frontend resources bundled by Webpack also have a type group ordering; JavaScript files loaded by `@JsModule` annotation come always before JavaScript files loaded by `@JavaScript`, and both of those come before CSS files loaded by `@CssImport`. The exception to this rule are `@JsModule` annotations of files annotated with `@Theme`. All JavaScript modules found on such classes are imported before other file types. This covers both `Lumo` and `Material` themes as well as custom themes created by the developer.

**Example**: Imported dependencies of different file types in a single class.

```java
@JavaScript("1.js")
@JsModule("a.js")
@CssImport("1.css")
@JavaScript("2.js")
@JsModule("b.js")
@CssImport("2.css")
static class OrderedDependencies extends Div {
}
```

- The loading order of the files will be: `a.js`, `b.js`, `1.js`, `2.js`, `1.css`, and `2.css`. Imports on other classes could be before or after the imports present here (within each file group).

You can control the load order of dependencies of different file types, by adding imports within an JavaScript import.

**Example**: Ensuring `custom-css.js` runs before `javascript-file.js`. The `custom-css.js` uses the technique for wrapping CSS into JavaScript presented in [Importing Style Sheets](https://vaadin.com/docs/v14/flow/styling/importing-style-sheets.md).

```javascript
import '../styles/custom-css.js';
import './javascript-file.js';
```

### <a id="using-the-loadmode-parameter"></a>Using the loadMode Parameter

> **Note:** `LoadMode` does not affect files that are bundled by Webpack. Those files will be included into the frontend resource bundle and will thus be available after the bundle has been loaded.

All annotations and methods in the `Page` class without explicit `LoadMode` parameter use `LoadMode.EAGER`, by default.

The `LoadMode` can be given as a parameter for the annotations or you can use the following methods in the `Page` class:

- `addStyleSheet(String url, LoadMode loadMode)`

- `addHtmlImport(String url, LoadMode loadMode)`

- `addJavaScript(String url, LoadMode loadMode)`

There are three available lode modes:

- `LoadMode.EAGER` is the default load mode for all dependencies. This mode ensures that the dependency is loaded as soon as possible, and before the initial page load.

  Eager mode is suitable in most cases. Use it if you are unsure which mode to use.

- `LoadMode.INLINE` inlines dependencies in the body of the page. This mode eliminates round trips when fetching dependencies. If the contents cannot be fetched, an exception is thrown and loading stops.

  > **Note:** Pay attention to URLs used for inlined dependencies: the URLS may change and could be incorrect after inlining.

- `LoadMode.LAZY` loads dependencies in the background, after all eager and inline dependencies have loaded. Lazy dependency loading is independent of page initialization.

  Lazy mode is suitable when you need to load the dependency, but it is not important when it is loaded.

### <a id="load-order-guarantees"></a>Load-Order Guarantees

- All eager and inline dependencies are guaranteed to load before lazy dependencies.

  Assume a component uses additional JavaScript animation, `/js/animation.js`, that is optional and not required, in your application. You can postpone its loading, giving priority to other resources.

  **Example**: Using annotations to add resource files.

  ```java
  @Tag("div")
  // same as @HtmlImport("/html/layout.html",
  //                     loadMode = LoadMode.EAGER)
  @HtmlImport("/html/layout.html")
  @StyleSheet(value = "/css/big_style_file.css",
          loadMode = LoadMode.INLINE)
  @JavaScript(value = "/js/animation.js",
          loadMode = LoadMode.LAZY)
  public class MainLayout extends Component {
      // implementation omitted
  }
  ```

  **Example**: Using `Page` class overload methods to add resource files.

  ```java
    public MainLayout() {
        UI.getCurrent().getPage().addHtmlImport(
              "/html/layout.html", LoadMode.EAGER);
        UI.getCurrent().getPage().addStyleSheet(
              "/css/big_style_file.css", LoadMode.INLINE);
        UI.getCurrent().getPage().addJavaScript(
              "/js/animation.js", LoadMode.LAZY);
    }
  }
  ```

  - In the examples, `/html/layout.html` is loaded and injected before creating the client-side structure for the `MainLayout` component, regardless of the availability of the `/js/animation.js` script.

- Dependencies with the same load mode are guaranteed to load in the order defined in the component. This is true for all load modes.

## <a id="resource-cheat-sheet"></a>Resource Cheat Sheet

### <a id="vaadin-14-with-npm"></a>Vaadin 14 with npm

Table 1. Non-Spring projects

| File type                        | Import                                                 | File location                     |
| -------------------------------- | ------------------------------------------------------ | --------------------------------- |
| CSS files                        | `@CssImport("./my-styles/styles.css")`[\[1\]](#foot-1) | `/frontend/my-styles/styles.css`  |
| JavaScript and Polymer templates | `@JsModule("./src/my-script.js")`[\[1\]](#foot-1)      | `/frontend/src/my-script.js`      |
| Static files, e.g. images        | `new Image("img/flower.jpg", "A flower")`              | `/src/main/webapp/img/flower.jpg` |

Table 2. Spring projects

| File type                        | Import                                                 | File location                                           |
| -------------------------------- | ------------------------------------------------------ | ------------------------------------------------------- |
| CSS files                        | `@CssImport("./my-styles/styles.css")`[\[1\]](#foot-1) | `/frontend/my-styles/styles.css`                        |
| JavaScript and Polymer templates | `@JsModule("./src/my-script.js")`[\[1\]](#foot-1)      | `/frontend/src/my-script.js`                            |
| Static files, e.g. images        | `new Image("img/flower.jpg", "A flower")`              | `/src/main/resources/META-INF/resources/img/flower.jpg` |

Table 3. Add-ons

| File type                        | Import                                                 | File location                                                          |
| -------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------- |
| CSS files                        | `@CssImport("./my-styles/styles.css")`[\[1\]](#foot-1) | `/src/main/resources/META-INF/resources/frontend/my-styles/styles.css` |
| JavaScript and Polymer templates | `@JsModule("./src/my-script.js")`[\[1\]](#foot-1)      | `/src/main/resources/META-INF/resources/frontend/src/my-script.js`     |
| Static files, e.g. images        | `new Image("img/flower.jpg", "A flower")`              | `/src/main/resources/META-INF/resources/img/flower.jpg`                |

### <a id="vaadin-10-13-vaadin-14-in-compatibility-mode"></a>Vaadin 10-13, Vaadin 14 in compatibility mode

Table 4. Non-Spring projects

| File type                                             | Import                                          | File location                                 |
| ----------------------------------------------------- | ----------------------------------------------- | --------------------------------------------- |
| CSS files                                             | `@StyleSheet("css/styles.css")`[\[2\]](#foot-2) | `/src/main/webapp/frontend/css/styles.css`    |
| Polymer templates, custom-style and dom-module styles | `@HtmlImport("src/template.html")`              | `/src/main/webapp/frontend/src/template.html` |
| JavaScript                                            | `@JavaScript("js/script.js")`[\[3\]](#foot-3)   | `/src/main/webapp/frontend/js/script.js`      |
| Static files, e.g. images                             | `new Image("img/flower.jpg", "A flower")`       | `/src/main/webapp/img/flower.jpg`             |

Table 5. Spring projects and add-ons

| File type                                             | Import                                          | File location                                                       |
| ----------------------------------------------------- | ----------------------------------------------- | ------------------------------------------------------------------- |
| CSS files                                             | `@StyleSheet("css/styles.css")`[\[2\]](#foot-2) | `/src/main/resources/META-INF/resources/frontend/css/styles.css`    |
| Polymer templates, custom-style and dom-module styles | `@HtmlImport("src/template.html")`              | `/src/main/resources/META-INF/resources/frontend/src/template.html` |
| JavaScript                                            | `@JavaScript("js/script.js")`[\[3\]](#foot-3)   | `/src/main/resources/META-INF/resources/frontend/js/script.js`      |
| Static files, e.g. images                             | `new Image("img/flower.jpg", "A flower")`       | `/src/main/resources/META-INF/resources/img/flower.jpg`             |

### <a id="footnotes"></a>Footnotes

1. The `@JsModule` and `@CssImport` annotations can also be used for importing from an npm package. In this case, the path is defined as `@JsModule("@polymer/paper-input")` or `@CssImport("some-package/style.css")`. Paths referring to the local frontend directory should be prefixed with `./`.

2. The `@StyleSheet` annotation can also be used in Vaadin 14 with npm. The same paths as in V10-V13 can be used, including the `context://` protocol `@StyleSheet("context://style.css")`, which resolves the path relative to the context path of the web application, like other static files. Styles included this way may cause issues with web components.

3. The `@JavaScript` annotation can also be used in Vaadin 14 with npm. The V14 `/frontend` folder should then be used.

`8BD21572-0F3E-4CE3-8536-02850F6149CC`
