Flow: Impossible to load assets from npm packages in style.css

Created on 26 Mar 2021  路  4Comments  路  Source: vaadin/flow

Description of the bug / feature

I'm following the documentation to load the assets from npm Package.
https://vaadin.com/docs/v14/flow/styling/custom-theme-configuration/#assets
But I have a 404 error when I'm using it in styles.css.

{
  "assets": {
    "@fortawesome/fontawesome-free": {
      "svgs/regular/**": "fontawesome/icons"
    }
  }
}
.icon-snowflake {
  background-image: url('fontawesome/icons/snowflake.svg');
}



md5-3ce64560a01fe22b0ca22f2bdba36d95



Image crmImage = new Image(
                "themes/myapp/fontawesome/icons/snowflake.svg",
                "Vaadin Brand");
        add(crmImage);



md5-e05738c1277533650601e18d7e8b4e71



@NpmPackage(value = "@fortawesome/fontawesome-free", version = "5.15.3")
@Route(value = "about", layout = MainView.class)
@PageTitle("About")
@CssImport("./views/about/about-view.css")
public class AboutView extends Div {

    public AboutView() {
        addClassName("about-view");
        addClassName("icon-snowflake");
        add(new Text("Content placeholder"));
        /*Image crmImage = new Image(
                "themes/myapp/fontawesome/icons/snowflake.svg",
                "Vaadin Brand");
        add(crmImage);*/
        add(new Html("<i class=\"fab fa-vaadin\"></i>"));
    }

}



md5-96e26ccccf75e6c319cdb5e10491ff41



.icon-snowflake {
    background-image: url('fontawesome/icons/snowflake.svg');
}



md5-6911ed3483c52ca1cea3534da9b0149e



{
  "assets": {
    "@fortawesome/fontawesome-free": {
      "svgs/regular/**": "fontawesome/icons"
    }
  },
  "importCss": [
    "@fortawesome/fontawesome-free/css/all.min.css"
  ]
}



md5-19125181ac764b020dd8a0615ec235f4



.icon-snowflake {
    background-image: url('/themes/myapp/fontawesome/icons/snowflake.svg');
}



md5-0f8a81cba198851ba9a235f7714a76ef



server.servlet.context-path=/context
High Major bug theming

All 4 comments

From Java and CSS, it should be fine to use

.icon-snowflake {
    background-image: url('fontawesome/icons/snowflake.svg');
}

```java
Image crmImage = new Image(
"fontawesome/icons/snowflake.svg",
"Snowflake");

since the asset is mapped with 
```json
{
  "assets": {
    "@fortawesome/fontawesome-free": {
      "svgs/regular/**": "fontawesome/icons"
    }
  }
}

@Artur- in https://github.com/vaadin/flow/issues/9535#issuecomment-737107336 you said that _it should go like in the prototype_ to be able to use theme/my-theme/fontawesome/icons/snowflake.svg and then some changes were made so that it works like that.
But actually in the story map @rolfsmeds this is specified as using things like above in my comment. So we are now going to fix it to work like above.

But it is a good question that should it also work by using the prefixed themes/my-theme/ ? From CSS, I would say no. From Java, I would say No to avoid using hard-coded magic strings. In the future we might have support for multiple runtime themes on the application, and as a Java developer you want to specify new Image("icons/snowflake.svg", "Snowflake"); where a different theme maps different set of resources to be used. And even there, IMO it would make more sense to be able to drop out the theme name from the url because that is hard-coded to the theme name. It seems at least easier if one doesn't have to use any code to get the name of the active theme, but to just let the framework redirect the request to the resource to the active theme.

We already support multiple themes through a parent theme. How do you load images/bg.png from the parent theme when it exists also in the child theme?

How do you load images/bg.png from the parent theme when it exists also in the child theme?

Should it even be possible to map assets to the same mapping in assets in both a parent and a child theme ? Or ever needed ? Not sure what happens now. At least I'm thinking we're not going to implement anything that starts going upwards from the child theme in checking where the resource is...

Easy would be just to say that it is not supported (to just reference the url from the assets mapping images/foobar.png). But not sure if it is good DX to require either
a) always prefixing the resources to the actual theme in both Java & CSS. This will be also problematic in Java at least if/when having multiple themes dynamically at runtime is possible (my bet is that it happens during this year)
b) have a different url-path to use depending on where there resource is being loaded (Java/CSS)

@rolfsmeds WDYT ?

My mental model of this feature is that the path to which an asset is mapped is relative to the root folder of the theme with the theme.json that does the mapping, i.e. : "fontawesome/icons" in mytheme/theme.json maps to themes/mytheme/fontawesome/icons, thus you should be able to refer to it within mytheme/styles.css as url("fontawesome/icons/snowflake.svg").

Having to prefix the url with /themes/mytheme would be weird if the referrer is in that same folder.

As for parent-themes, my mental model of them is that they're available as sibling-folders to the used sub-theme, so themes/mytheme can refer to themes/basetheme by ../basetheme.

As for npm-mapping in parent/sub themes, following the above model, mapping to fontawesome/icons in basetheme/theme.json would mean that the asset is available, for the sub-theme, in ../basetheme/fontawesome/icons, in which case sure, you have to refer to the parent theme by name, but the same applies if you want to refer to a real path in the parent theme from the child theme, e.g. basetheme/logo.png could be referred to from the sub-theme as url('../basetheme/logo.png').

Not sure about the java side. Seems to me that it would be good to have an standard way to point to an asset from the currently applied theme without having to use its name, but I would consider that an enhancement.

So I suggest we start by poking holes in my mental model, and take it from there :)

Was this page helpful?
0 / 5 - 0 ratings