Using webcomponents library with phoenix 1.7


I’m trying to use with Phoenix, the idea is use web components in client and hooks to interact with Phoenix.

I can see the component but the styles its impossible.

How is the way to use js and css from a component library in order to use easily in Phoenix 1.7?


The default assets management is split between js and css. Js is handled by esbuild, css is handled by tailwindcss cli. You can either make tailwind import shoelace css or handle shoelace css with esbuild, by linking the css file it’ll built in your root layout root.html.heex.

1 Like

Phoenix is frontend pipeline agnostic. I’ve use it with webpack, snowpack, esbuild, Vite or no build step at all. Everything is possible; however, there may not be a step by step tutorial that match your needs exactly. IMHO, most tutorials off the internet are not very valuable; you are better off figuring it out on your own.


One of the aspects I appreciate about these tools, particularly the Tailwind CSS CLI, is their versatility. They can be utilized even when Tailwind CSS isn’t the primary styling method for the templates.

In projects where other CSS frameworks like Bulma are used instead of Tailwind CSS, I believe it’s not necessary to remove the Tailwind configuration. It worked fine for me at least.

However, it’s worth noting that the Tailwind CSS CLI lacks some features like SASS assets management. Fortunately, we have an alternative solution in Dart Sass.

The great news is that we can use both the Tailwind CSS CLI and Dart Sass together. The approach would be to first build an output file with Dart Sass (perhaps named app.css.tailwind), which would then be processed by the Tailwind CSS CLI. It worked fine for me at least.

For a detailed explanation on this process and other aspects of assets management, I recommend checking out this tutorial: Using Tailwind CSS in Phoenix.

We use Shoelace with Phoenix. It’s working great, but you have to understand how web components works. Styling web components is different because they use Shadow DOM. Shoelace have a section in docs explaining that, but it’s general to all web components.


Hi @oleksify are you using shoelace with LiveView or dead views? I am asking because I was under the impression that it is not possible to use shoelace easily with LiveView due to this issue. I would love to know if the situation has changed :slight_smile:

We do use it with LV. We did not hit this issue yet, also we’re not using Button component and we’re careful with attributes in general.

Everything has been working great so far. though it’s not that easy with LV. We build layer on top of Shoelace and our own web components. So, we have LV component wrapping Web Component and passing down the props, event handlers, etc. Then, we also add hooks for each components where we get passed down even names and add JS handlers for them or wire to Shoelace events. Or add event listeners for Shoelace events.

We did try but decided to go on our own, to have more control over everything.

So far, web components (native custom elements) is the best thing (IMO) you can use for complex client-side UI in Phoenix.Mainly, because you slot html from phoenix inside and everything will just work. This is not possible with React and co, where you cant wrap some html from server with component - you have to pass everything through props, etc.


Do you recommend web components with Shadow DOM over a CSS library like daisyui?


Short answer - Yes, absolutely.
Long answer - it all depends on the complexity of your app. Sometimes simple things like DaisyUI is enough. But when you need good a11y with more complex components - like dropdowns, combo boxes, keyboard navigation, tooltips that know how to behave depending on surrounding space - you will hit CSS solutions limitations. If that’s your case - I would suggest using web components.

Just keep in web components specifics - Shadow DOM behave in a specific way. You have styles scoping and isolation which is really cool. But then, you can hit problems with forms, for example. If you have shadow DOM input within light DOM form - it will be invisible to your form. Shoelace fixes this so it’s safe to use their components - but when you start grabbing components from github - keep that in mind.

Thanks for your answers

1 Like