Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ Store frontend sources, such as CSS files and JavaScript, in the `src/main/front

=== Multiple UI Modules

If you are using *package by feature*, you'll have more than one UI module. In this case, you should treat the UI modules as Vaadin *add-ons*. This means you have to store module-specific CSS files, JavaScript, and images in the `src/main/resources/META-INF/resources` directory. See <</flow/advanced/loading-resources#,Loading Resources>> for more information.
If you are using *package by feature*, you'll have more than one UI module. In this case, you should treat the UI modules as Vaadin *add-ons*. This means you have to store module-specific CSS files and static resources, such as images, in the `src/main/resources/META-INF/resources` directory, and JavaScript modules in the `src/main/resources/META-INF/frontend` directory. See <</flow/advanced/loading-resources#,Loading Resources>> for more information.

Add the theme files and the Vaadin Maven plugin to the _application module_, which is covered in the next section.

Expand Down
35 changes: 23 additions & 12 deletions articles/building-apps/components/package-component.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ my-component/
│ │ │ └── TheAddon.java
│ │ └── resources/
│ │ └── META-INF/
│ │ └── resources/
│ │ └── frontend/
│ │ └── frontend/
│ └── test/
│ └── java/
│ └── org/vaadin/addons/mygroup/
Expand Down Expand Up @@ -85,41 +84,53 @@ The starter includes a `directory` Maven profile that builds a ZIP file for the

== Frontend Resources

If your add-on includes CSS, JavaScript, or TypeScript files, place them under:
If your add-on includes JavaScript or TypeScript modules, or CSS files that should be included in the frontend bundle, place them under:

----
src/main/resources/META-INF/resources/frontend/
src/main/resources/META-INF/frontend/
----

Files in this location are automatically discovered by Vaadin when the add-on JAR is on the classpath. Reference them from your Java component with `@JsModule` or `@CssImport`:
Files in this location are automatically discovered by Vaadin when the add-on JAR is on the classpath, and are processed by the Vite build pipeline. Reference them from your Java component with `@JsModule` or `@CssImport`:

[source,java]
----
@CssImport("./my-component/status-badge.css")
@JsModule("./my-component/status-badge.js")
public class StatusBadge extends Composite<HorizontalLayout> {
// ...
}
----

The `./` prefix maps to the `frontend/` directory on the classpath, which includes your `META-INF/resources/frontend/` files.
The `./` prefix maps to the `frontend/` directory on the classpath, which includes your `META-INF/frontend/` files.

Add-ons use `@CssImport` rather than `@StyleSheet` because their frontend resources are placed in `META-INF/resources/frontend/`, which is processed by the Vite build pipeline. `@StyleSheet` resolves against the static resources root, `META-INF/resources/`, and is the standard approach for application code — see <<style-component#,Style a Component>>.
During development, you can also use `src/main/frontend/` for convenience — Vaadin picks up files from there as well. However, only files in `META-INF/frontend/` are included in the published JAR.

During development, you can also use `src/main/frontend/` for convenience — Vaadin picks up files from there as well. However, only files in `META-INF/resources/frontend/` are included in the published JAR.
[NOTE]
.Deprecated Location
Some earlier add-ons place frontend files in `src/main/resources/META-INF/resources/frontend/` instead. That location still works, but it's deprecated: everything under `META-INF/resources/` is also published as static resources, so the un-bundled source files are served directly to browsers — which is usually not what you want. Use `META-INF/frontend/` so the files are only used as input for the frontend bundle.


== Including Stylesheets

For components that need CSS, you have two options:
CSS files typically go in the static resources folder, `src/main/resources/META-INF/resources/`, and are loaded with `@StyleSheet` — the same approach as in application code (see <<style-component#,Style a Component>>):

[source,java]
----
@StyleSheet("my-component/status-badge.css")
public class StatusBadge extends Composite<HorizontalLayout> {
// ...
}
----

The path resolves against the static resources root, so the example above loads `src/main/resources/META-INF/resources/my-component/status-badge.css`.

*Application-scoped CSS* — use `@CssImport` to load a stylesheet into the application:
If you want the CSS to be included in the frontend bundle instead of served as a separate file, place it in `META-INF/frontend/` and load it with `@CssImport`:

[source,java]
----
@CssImport("./my-component/status-badge.css")
----

*Component-scoped CSS for Vaadin components* — to inject styles into a Vaadin component's shadow DOM, use the `themeFor` attribute:
`@CssImport` is also needed to inject styles into a Vaadin component's shadow DOM, using the `themeFor` attribute:

[source,java]
----
Expand Down
2 changes: 1 addition & 1 deletion articles/building-apps/components/style-component.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ The lazy approach is useful for components with significant CSS that isn't neede

[NOTE]
.Add-On JAR Packaging
If you're packaging the component as a reusable add-on JAR, CSS files go in `META-INF/resources/frontend/` and are loaded with `@CssImport` instead. See <<package-component#,Package a Component>> for details.
If you're packaging the component as a reusable add-on JAR, use the `@StyleSheet` approach — the consuming application's `styles.css` isn't available to the add-on, so you can't import from it. See <<package-component#,Package a Component>> for details.

=== Use Theme Custom Properties

Expand Down
2 changes: 1 addition & 1 deletion articles/components/map/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ import com.vaadin.flow.server.streams.DownloadHandler;

// Assuming the given image is in the JAR resources
DownloadHandler downloadHandler = DownloadHandler.forClassResource(
getClass(), "/META-INF/resources/frontend/custom-cluster.png",
getClass(), "/images/custom-cluster.png",
"custom-cluster.png").inline();
Icon.Options iconOptions = new Icon.Options();
iconOptions.setImg(downloadHandler);
Expand Down
10 changes: 8 additions & 2 deletions articles/flow/advanced/loading-resources.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,16 @@ The following tables show how to load various resources and where the resource f
|File type |Import |File location

|CSS files
|`@StyleSheet("my-styles/styles.css")`<<foot-1,[1]>>
|`/src/main/resources/META-INF/resources/my-styles/styles.css`

|CSS files included in the frontend bundle
|`@CssImport("./my-styles/styles.css")`<<foot-1,[1]>>
|`/src/main/resources/META-INF/resources/frontend/my-styles/styles.css`
|`/src/main/resources/META-INF/frontend/my-styles/styles.css`<<foot-3,[3]>>

|JavaScript, TypeScript and Lit templates
|`@JsModule("./src/my-script.js")`<<foot-1,[1]>>
|`/src/main/resources/META-INF/resources/frontend/src/my-script.js`
|`/src/main/resources/META-INF/frontend/src/my-script.js`<<foot-3,[3]>>

|Static files, such as images and icons (for example, the favicon)
|`new Image("img/flower.jpg", "A flower")`
Expand All @@ -101,6 +105,8 @@ Anchor anchor = new Anchor("assets/document.pdf", "A document");
anchor.getElement().setAttribute("router-ignore", true);
----

. [[foot-3]]Some earlier add-ons use the `/src/main/resources/META-INF/resources/frontend` folder instead. That location still works, but it's deprecated: everything under `META-INF/resources` is also published as static resources, so the un-bundled source files are served directly to browsers.


== Programmatically Load Resources

Expand Down
2 changes: 1 addition & 1 deletion articles/flow/configuration/properties.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@
Mode: Development

`**frontend.hotdeploy.dependencies**`::
A comma-separated list of module directories to watch for frontend file changes when detecting hot-deployable resources. Entries need to point to directories relative to the module that starts the Vaadin application, and can point to the module itself as well, in case it provides frontend files as resources. The value could be for example "./,./component-module-1,./component-module-2". Flow will watch for changes in both `src/main/resources/META-INF/resources/frontend` and the legacy `src/main/resources/META-INF/frontend` directories under the given three directory entries. Do note that if this parameter is not defined, Vaadin watches for changes under `src/main/resources/META-INF/` in the module that starts the Vaadin application, but when you provide a custom value for the parameter you need to add "./" to the list of directories to watch for the same effect. +
A comma-separated list of module directories to watch for frontend file changes when detecting hot-deployable resources. Entries need to point to directories relative to the module that starts the Vaadin application, and can point to the module itself as well, in case it provides frontend files as resources. The value could be for example "./,./component-module-1,./component-module-2". Flow will watch for changes in both `src/main/resources/META-INF/frontend` and the deprecated `src/main/resources/META-INF/resources/frontend` directories under the given three directory entries. Do note that if this parameter is not defined, Vaadin watches for changes under `src/main/resources/META-INF/` in the module that starts the Vaadin application, but when you provide a custom value for the parameter you need to add "./" to the list of directories to watch for the same effect. +

Check warning on line 231 in articles/flow/configuration/properties.adoc

View workflow job for this annotation

GitHub Actions / lint

[vale] reported by reviewdog 🐶 [Vaadin.NoteThat] Avoid using 'note that'. Raw Output: {"message": "[Vaadin.NoteThat] Avoid using 'note that'.", "location": {"path": "articles/flow/configuration/properties.adoc", "range": {"start": {"line": 231, "column": 589}}}, "severity": "WARNING"}

Check warning on line 231 in articles/flow/configuration/properties.adoc

View workflow job for this annotation

GitHub Actions / lint

[vale] reported by reviewdog 🐶 [Vaadin.Will] Avoid using 'will'. Raw Output: {"message": "[Vaadin.Will] Avoid using 'will'.", "location": {"path": "articles/flow/configuration/properties.adoc", "range": {"start": {"line": 231, "column": 395}}}, "severity": "WARNING"}
Default: `""` +
Mode: Development

Expand Down
Loading