HTML Web Components
18:47
3 ай бұрын
Episode 141 - My obsidian setup
10:19
Episode 134: The craft of the web
1:56
Episode 133: Learning JavaScript
14:40
The problem with SPAs (they suck!)
4:17
Пікірлер
@KeshavPanchal
@KeshavPanchal Күн бұрын
Please keep making content on web components!🎉
@ChrisWeber
@ChrisWeber Күн бұрын
Where is the follow up to this video? You talked about decoupling the data storage. I would love to see your implementation.
@StevenJuarezIR
@StevenJuarezIR 2 күн бұрын
This is great content. Straight the the point and easy to follow. Please do more on web components and maybe a video on using web components with htmx.
@terrencemoore8739
@terrencemoore8739 11 күн бұрын
Im surprised you havent mentioned htmx at all, it seems like it'd be right up your alley. HTMX + web components + Reef would be an insane combo
@gomakethings
@gomakethings 10 күн бұрын
Believe it or not, I *HATE* HTMX with a passion: gomakethings.com/why-not-htmx/
@terrencemoore8739
@terrencemoore8739 9 күн бұрын
@@gomakethings yea, I get those reasons. I think both creators have similar goals, it's just achieved in different ways. I will say I'd rather use HTMX than make a whole component just to replace some HTML. I also had some issues working with Reef today. It's weird, it works but not as straightforward as it seems, one time I had to switch to using a store to get it working, the issue I ran across today involved component only rendering for one of instances unless I set the innerHTML first. After spending a while trying to use uuid and swapping between store, signal, component and render, I just wrote it in vanilla js instead. It's tough to debug because it doesn't throw exceptions
@gomakethings
@gomakethings 9 күн бұрын
@@terrencemoore8739 Please feel free to open an issue on GitHub. I'd be happy to look at what's going on.
@terrencemoore8739
@terrencemoore8739 11 күн бұрын
Your library looks very cool! I will definitely be using it
@terrencemoore8739
@terrencemoore8739 11 күн бұрын
It feels like the missing link to solve my desire for modern frontend without needing to use some bastardized version of JavaScript to do it. I was also looking at Proxy. It seems Reef functions more like Signals. Are you familiar with JavaScript's Proxy? If so, could you explain how they're different?
@terrencemoore8739
@terrencemoore8739 11 күн бұрын
Just looked at the GitHub, I was trying to do signals the other day but you figured out where I got stuck: the handler methods for signals. Brilliant idea!
@terrencemoore8739
@terrencemoore8739 11 күн бұрын
Thought I responded to this but I looked at the GitHub for it, it does use Proxy. I couldn't figure out how to get from a proxy to a signal because of the handler. Your implementation is great. I wasn't able to find the non-jsx preact code you were talking about but I feel like this plus web components and maybe some HTMX is all I need
@MDABDULMOMINRiyadh
@MDABDULMOMINRiyadh 14 күн бұрын
Love It!
@svivian
@svivian 16 күн бұрын
Hey, just a little thing but a few times (e.g. 12:15) your coding was covered up by your picture. Might want to scroll a bit in future to keep the code visible :)
@gomakethings
@gomakethings 15 күн бұрын
Ah crap, sorry I missed that! I'll do better in the next one!
@svivian
@svivian 8 күн бұрын
@@gomakethings No worries. I'm loving these videos!
@gianbattistamaricosu1911
@gianbattistamaricosu1911 16 күн бұрын
a tabs system with web components would be very useful
@gomakethings
@gomakethings 15 күн бұрын
EXCELLENT suggestion!
@cloudpuncher4615
@cloudpuncher4615 16 күн бұрын
Love your content... I wish I had found it 12years ago... It would have saved me lot of time on my VaJS journey...
@TimFegan
@TimFegan 17 күн бұрын
Very interesting. I like how simple you made this look. I was wondering if it would beneficial to make more components as one would tend to do in React. So, even though the Square is basically just a button, it does have state of ' ', 'X' or 'O'. Or on the other hand, from the way you explain Web components before where wrap vanilla HTML in the HTML file with a Web Component, could you take most of the HTML out of the component and place it into the vanilla HTML section.
@gomakethings
@gomakethings 17 күн бұрын
The reason I don't do that is because, frankly, I think the "react way" of building most UI is bad. It adds a LOT of extra complexity under the guise of scalability and simplicity.
@TimFegan
@TimFegan 17 күн бұрын
@@gomakethings Good point.
@davidluhr
@davidluhr 17 күн бұрын
What's your typical threshold for when to use state-based UI? When traditional DOM manipulation is becoming too much? I have a project that might be at this threshold. The project involves an and a UI that modifies content inside the . When the user interacts with the UI, we dispatch a custom event to update the , update it, then dispatch a custom event to update the UI. This was fine for a while but some updates to the UI were getting quite complex. For now, I switched to simply re-rendering the UI and managing keyboard focus for accessibility. It doesn't seem to harm performance at this scale, but it's a potential future issue. With a state-based UI approach, I guess I would maintain a central data object that represents the shared state of both the and the UI? Reef may be a good fit for my needs in this case.
@gomakethings
@gomakethings 17 күн бұрын
For me, that threshold is usually when I have multiple pieces of UI all modified by the same piece of data or state. Below that threshold, state-based UI often feels like more work.
@davidluhr
@davidluhr 17 күн бұрын
@@gomakethings That's helpful criteria, and is what I'm experiencing with keeping an 's DOM and the representation of that DOM with a UI in sync.
@dmh5220
@dmh5220 17 күн бұрын
Great stuff
@gomakethings
@gomakethings 17 күн бұрын
Thank you!
@kanaillaurent526
@kanaillaurent526 17 күн бұрын
Wow glad I inspired u haha. Or maybe not. Let's watch this.... If I understood well, line 118 will act like each time u change the object square it will trigger a rendering.
@gomakethings
@gomakethings 17 күн бұрын
That's correct! In most state-based UI libraries, a signal detects changes to its value and automatically causes a render to happen.
@rebelmachine88
@rebelmachine88 18 күн бұрын
This is a great showcase of how easy/simple web components are compared to React. I would love to see more direct comparisons like this project!
@gomakethings
@gomakethings 17 күн бұрын
Happy to keep creating them. Really appreciate the kind words!
@frumbert
@frumbert 20 күн бұрын
You could build a tic tac toe using html, no javascript. Lots of files though, one for each state the board could be in. Clicking a cell links to the hpertext file representing the new state. Inherent history/undo as well. That way it could even work on the Lynx browser.
@gomakethings
@gomakethings 17 күн бұрын
I absolutely love HTML-only stuff like that. And I totally see it. Links, with a few dozen HTML files for the various combinations that could exist.
@terryweb
@terryweb 20 күн бұрын
Amazing tricks, except #13... 😀
@gomakethings
@gomakethings 17 күн бұрын
I won't hold it against you that you pronounce GIF wrong ❤
@IainSimmons
@IainSimmons 21 күн бұрын
Great video! I'd love to see more of these types of videos, comparing JS framework code to regular light DOM HTML web components! One thing about your app logic... Can you not just use the fact that the next move alternates between X and O and whether the index of the history is odd or even to determine what it should be? And can you just remove the list items and history with an index higher than the clicked one, in handleJumpTo?
@gomakethings
@gomakethings 17 күн бұрын
I plan to keep making them. Thanks so much!
@kanaillaurent526
@kanaillaurent526 21 күн бұрын
Thank you I like that. This is how I work too with webcomponents: TDD on the browser when the webcomponent is not very complicated. Also I used to store the state in the DOM too but I've changed my method because I've founded that it's more complicated in a complex application. Now i store the state of the whole application in a centralized object (a little bit like redux does). Unfortunately I don't have the observation (subscribe and dispatch) mecanism yet in place but I'm working on it.
@svivian
@svivian 22 күн бұрын
“I like to use const for everything” *immediately changes const to let* 😆
@chritical_ep
@chritical_ep 20 күн бұрын
He might have misspoke, I remember in one newsletter he said he used let for everything, so he might have got them switched up
@gomakethings
@gomakethings 17 күн бұрын
Oh shit, I totally misspoke. I meant to say "I like to use let for everything." That hilarious, actually! 😂😂😂
@dovh49
@dovh49 23 күн бұрын
Van JS is a good alternative too. I was thinking for the history creating a square custom element and then storing all that information in there and then looping through the custom elements to update any history. Like `square.removeHistory(3)` Where 3 would be the history index. And when adding a value you can do `square.setValue('X', historyIndex)`. Something like that. Then you have a different class handling a lot of the things.
@terrencemoore8739
@terrencemoore8739 23 күн бұрын
Amazing video idea. I always wondered how different making custom web components are to react implementations
@terrencemoore8739
@terrencemoore8739 22 күн бұрын
Just tried making a web component without using the shadow dom, it worked great!
@gomakethings
@gomakethings 17 күн бұрын
@@terrencemoore8739 Thanks for the kind words, and that's AWESOME to hear!
@SuicideDog
@SuicideDog 23 күн бұрын
im starting out in development. done a 2 year course on front-end where a lot of focus was on react. i feel like there are a lot of basic javascript knowledge that has flown over my head by transitioning over to react too quickly. I really like this type of content. because by comparing and practicing vanilla. It at least feels like i get a deeper understanding on how the language work, and how different programming logic and approaches can be applied. so super thankful:)
@cloudpuncher4615
@cloudpuncher4615 23 күн бұрын
How did you write the Custom Element innerHTML in the constructor? I get an error unless I attachShadow and write the shadowRoot innerHTML....
@dovh49
@dovh49 23 күн бұрын
The source code is in the description. Maybe you're doing something that is a little off?
@gomakethings
@gomakethings 17 күн бұрын
I do it all the time. Never run into an issue before.
@cloudpuncher4615
@cloudpuncher4615 17 күн бұрын
@@gomakethings My bad, u cant append elements to a CE inside the constructor but you can to the shadowRoot...
@gomakethings
@gomakethings 17 күн бұрын
@@cloudpuncher4615 You can do that, too. Here's a demo: gist.github.com/cferdinandi/39774222f289c2d6eee22282350e0eea
@cloudpuncher4615
@cloudpuncher4615 17 күн бұрын
@@gomakethings Thanks for the reply.... it appear that you can (in chrome) only if you put the <script> after the Custom Element lest you get this error .."Uncaught DOMException: Failed to construct 'CustomElement': The result must not have children"... .For whatever reason it will append to a shadowRoot or append during the during the Custom Element upgrade. You can just do it with connectedCallback() no issues but it would be nice to just create elements and pass in data in the constructor..
@davidluhr
@davidluhr 24 күн бұрын
This is a great demonstration of the value of writing vanilla JavaScript: When you write framework code, you improve your skills in the framework. When you write vanilla JavaScript, you improve your skills in JavaScript as a whole. Sure, you use some vanilla JavaScript in React, but it's a narrower slice. Even if you create solutions that can React solve in its own way, your solution is tailored to your specific needs and context, and you gain more transferable knowledge along the way.
@gomakethings
@gomakethings 17 күн бұрын
Thanks for the kind words, David!
@joelhayes9477
@joelhayes9477 16 күн бұрын
My main issue with development is components are supposed to be reusable, but in frameworks, all of my code eventually gets deprecated by the framework. Meanwhile, that one lazy load function I wrote in vanilla JS has lasted 10 years hahha. I'm really glad I found this channel!
@k16e
@k16e 24 күн бұрын
JavaScript owes you, mentor. Then so does the community. Thanks for keeping me in check.
@gomakethings
@gomakethings 17 күн бұрын
Cheers KB!
@bourge
@bourge 27 күн бұрын
I ran into problems when i tried to use a vanilla WC in a Next.js. Turns out SSR apps are not to friendly to WCs. Are there any thing we can do to solve this?
@gomakethings
@gomakethings 24 күн бұрын
I'd need more specifics about the errors you're seeing to answer that.
@bourge
@bourge 24 күн бұрын
@@gomakethings There are flash effects on every page loads. This is only for Nextjs apparently due to the way it handles hydration of the DOM.
@gomakethings
@gomakethings 17 күн бұрын
@@bourge I wonder if you're seeing flashes of unstyled content, or if the Web Components are being replaced and re-rendered because of hydration.
@bourge
@bourge 17 күн бұрын
@@gomakethings it is the rerendering during hydration. I heard that a new spec called declarative shadow dom could help. I wish though that NextJs would better support web components.
@Alex-BSD
@Alex-BSD 28 күн бұрын
The CV says "senior" but the code has "document.getElementById"
@FlorianSchommertz
@FlorianSchommertz 28 күн бұрын
Am I correct that not using shadow DOM forces you to run the script after the DOM has loaded?
@gomakethings
@gomakethings 24 күн бұрын
No, that's just how DOM manipulation works in general. It's not specific to the shadow DOM (or lack thereof). If you target elements that don't exist yet, you'll get errors.
@tubeta028
@tubeta028 29 күн бұрын
I like this, good video thanks
@gomakethings
@gomakethings 24 күн бұрын
Thanks!
@YoungLink51423
@YoungLink51423 Ай бұрын
Starting this series now
@ba8e
@ba8e Ай бұрын
Why shuffle the array when you can just get a random index? array[Math.floor(Math.random() * array.length)]
@gomakethings
@gomakethings 24 күн бұрын
Historically, the Fisher-Yates shuffle produced more random results than a simple Math.random(), which tends to skew towards the middle over time. MDN used to have details about this on their site, but they're not longer there.
@CristianKirk
@CristianKirk Ай бұрын
Thanks a lot. This series is being very useful and it's hard to believe there are no more channels teaching about web components..
@gomakethings
@gomakethings 24 күн бұрын
Thank you!
@pl4gueis
@pl4gueis Ай бұрын
"Developer ergonomics and ease of authoring code" holds true for the first 5 minutes of developing react. Once you add all the hooks, router, redux, component library, jss its all over. Adding abstractions to fix the horrible abstractions until you have a mess that is most react projects.
@gomakethings
@gomakethings 24 күн бұрын
Couldn't agree more!
@damvaz
@damvaz Ай бұрын
Great content!!! Ideas for new contents? What about "making a new simple design system" (framework agnostic) using web componentes and css best practices?
@gomakethings
@gomakethings 24 күн бұрын
That's a great suggestion, thanks!
@evilspymace209
@evilspymace209 Ай бұрын
i'm guilty for using web components as an alternative to vue. right now i'm rewriting a SPA. i wanted to avoid the excessive tooling and ever changing apis. honestly it's so much more fun!
@pl4gueis
@pl4gueis Ай бұрын
Great series. How would I go about writing tests for these web components?
@gomakethings
@gomakethings 24 күн бұрын
Same way you'd test any DOM manipulation component. Jest is well suited to it, I think.
@BenHewart
@BenHewart Ай бұрын
I think its great that a youtube channel is finally doing native web components! I love it... and love web components but I think I disagree with the shadow dom being an anti pattern and styling is way easier being encapsulated... components are mean't to be self contained so they can be used through out any project without clashes with global code. if you want global styling the you simply create a global style sheet and use custom properties ( or css variables ) Global style sheet: :root { --bg-blue: ##4187f7; } component styles: <style> background-color: var(bg-blue); </style> Another issue mixing light and shadow dom is CLS obviously light dom will load first loading content first and then loads in shadom dom after this causing jumping, as far as I can see its better to stick to the shadom dom or the light not to mix them.... otherwise you will have to constantly reserve space for the shadow dom Open if anyone has any other solutions? Still learning all the awesomeness of web components thanks and keep up the great work!
@gomakethings
@gomakethings 24 күн бұрын
I think this is a symptom of thinking about Web Components as React components rather than their own, unique thing. React has poisoned the web well. gomakethings.com/html-web-components/
@BenHewart
@BenHewart 24 күн бұрын
Oh I totally agree that react has ruined the web.... I am massive on core web vitals and have built a web app using only native web components with html CSS and vanilla js.... That scores 100 across the board... The problem I found and if you have any suggestions is that if you mix the light Dom and the shadow dom it causes CLS... So the only way was to use web components that are self contained.
@gomakethings
@gomakethings 24 күн бұрын
@@BenHewart Forgive me, but what does CLS stand for?
@BenHewart
@BenHewart 24 күн бұрын
CLS (Cumulative Layout Shift) measures visual stability in Core Web Vitals. It quantifies how much elements on a page move unexpectedly as it loads. High CLS means a poor user experience, as content shifting can disrupt interactions. As the light Dom loads first and then native web components it can make elements jump about as the page loads hence I went for a full shadow dom component to fix this
@BenHewart
@BenHewart 24 күн бұрын
Happy to show you if your interested no pressure 😉
@rustyprogrammer
@rustyprogrammer Ай бұрын
Thanks, very clear :-). I wonder why, in the count component, you inherit from the HTMLElement and not directly from HTMLButtonElement?
@gomakethings
@gomakethings Ай бұрын
This comes up a lot! There are two reasons: 1. The Web Component itself isn't a button. One of it's child elements is. If I wanted the custom element itself to behave like a button, I'd also need to add stuff like a `role` attribute and additional event listeners. 2. That's also unfortunately not how Web Components work. You extend the HTMLElement, then layer in your custom behavior. You can't reliably extend other element types with customElements.define(). There was a spec in the works that would let you extend native elements with custom functionality using `is` attribute. Firefox and Chromium moved forward with it, and then the WebKit team straight up refused to implement it, effectively killing the spec. developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/is My understanding is that there's a replacement spec in the works that WebKit is allegedly onboard with, but I don't know much about it at this time as it's nowhere near production ready.
@etherweb6796
@etherweb6796 Ай бұрын
The answer is yes
@coderlicious6565
@coderlicious6565 Ай бұрын
Do you think this is a good way to go, using a cloudflare serverless function, if you're creating a chrome extension that calls the Notion api ( but notion doesn't allow you to make calls from the extension ). I need something somewhere on a paid server, that receives some text data, and then makes the call to notion api which makes notion happy. I was also looking at supabase for their serverless function capability.
@gomakethings
@gomakethings Ай бұрын
Could be! Could get expensive for a public extension, of course. The whole benefit of "serverless" is that you don't have to worry about maintaining the server, just the function (or functions) that run on it.
@kodejohan
@kodejohan Ай бұрын
Very interesting approach!
@gomakethings
@gomakethings Ай бұрын
Thanks!
@sonnyl2915
@sonnyl2915 Ай бұрын
Luv it! Question: I've got troubled running into swapping elements issue. How do you have all the elements within the web-component readily in order for execution by the DOM? Sometimes in the console window said undefined or not found?
@gomakethings
@gomakethings Ай бұрын
I wrote a little bit about this a few weeks ago: gomakethings.com/the-different-ways-to-instantiate-a-web-component/ If you have a specific example in a code pen or GitHub repo you'd like me to look at, though, that works too!
@cmilne10
@cmilne10 Ай бұрын
great series. Informative and simple
@gomakethings
@gomakethings Ай бұрын
Cheers!
@terhuneb
@terhuneb Ай бұрын
Thank you for mentioning an ES Module implementation too.
@gomakethings
@gomakethings Ай бұрын
You're welcome!
@dirtdart81
@dirtdart81 Ай бұрын
Really enjoying this series! I'm not new to programming, but new to web/js and it is an interesting time to be learning. As flavor of the week frameworks go in and out, this kind of 'back-to-basics' feels timely. Thanks for the videos!
@gomakethings
@gomakethings Ай бұрын
You're welcome! If you have any questions along the way, feel free to ask!
@jonathanoden6854
@jonathanoden6854 Ай бұрын
Hello, thank you very much for the work you are doing in sharing good practices on how the web could be done! Web components didn't clicked for me until I saw your daily tips. I had this bad feeling using shadow dom and kind of full javascript components. Now, with 'enhanced html elements' it feels really nice and deeply connected to html and css. I see here you are using attributes without 'data-' prefix, is there a reason for that? Again, thanks a lot!
@gomakethings
@gomakethings Ай бұрын
They're invalid, and I should probably stop doing it. In my mind, if I'm creating a custom element, I like to use custom attributes with it. An HTML validator will complain about them, but CSS and JavaScript will work with them just fine. For safety, I could also add a dash to the names to ensure no conflicts with future attribute names. I lean heavily on attributes in my web components, and having to write data-* constantly is fatiguing, IMO.
@NeilMerton
@NeilMerton Ай бұрын
I’m enjoying the series, thanks for putting these together 👍 Do you have any plans on showing option on how to encapsulate the web component code within the component itself and how that then gets consumed by the HTML? I hope this makes sense.
@gomakethings
@gomakethings Ай бұрын
Thanks! Can you clarify what you mean by this: "ow to encapsulate the web component code within the component itself and how that then gets consumed by the HTML?" I'd be delighted to make a vide about if, once I better understand what you're asking.
@NeilMerton
@NeilMerton Ай бұрын
Sure. What I see in these two videos is you’ve got the ‘pick-at-random.html’ file that contains ‘pick-at-random’ element and below that the JavaScript to make it work. How is this then reusable? For example, I’d like to use it on a different page, how would I go about doing that. Let me know if you’d like me to elaborate further.
@gomakethings
@gomakethings Ай бұрын
@@NeilMerton Yep, that helps a lot. Thanks Neil!
@netssrmrz
@netssrmrz Ай бұрын
The event management feels clumsy. Do you have or could you do a video covering it in more detail? As in pros and cons compared to other methods. I'm wondering if I should change my approach.
@gomakethings
@gomakethings Ай бұрын
That's a good suggestion, thanks!
@NicklasIsraelsson
@NicklasIsraelsson Ай бұрын
Thanks for sharing! Very nice. Looking forward to the next session. One thing I would like to see is the thing at the end you briefly mentioned. How would you "upgrade" this to use the dialog element instead of confirm?
@gomakethings
@gomakethings Ай бұрын
GREAT suggestion! Let me add that to the list!
@sanderlissenburg1608
@sanderlissenburg1608 Ай бұрын
It's better to use the connectedCallback instead of the constructor. I ran into an issue that the javascript was loaded before the dom was loaded/ready. This is because I load the javascript in the head instead of the bottom of the page. I know I know I should change that. Either way I think using the connectedCallback is still better.
@gomakethings
@gomakethings Ай бұрын
"Better" isn't the word you're looking for. "Can prevent issues in certain contexts." The problem you're describing can still happen even when using connectedCallback. There are a bunch of strategies to fix it. But in your case, DOM scripts should be loaded in the footer or use async/defer or be wrapped in a DOMContentLoaded event. What you're describing would happen if you were using plain old DOM manipulation methods, too. More on all of that here: gomakethings.com/the-different-ways-to-instantiate-a-web-component/
@sanderlissenburg1608
@sanderlissenburg1608 Ай бұрын
Thnx for the reply and extra info!