Description
The Generic Drupal Web Components project aims to create a library of web components that are accessible, framework agnostic, possible to style, and easy to use with data provided by Drupal. In support of the Decoupled Menus initiative, an initial menu component was created as a proof of concept. This talk will focus on the lessons learned creating this menu component, and how this model could be followed to create a full design system that could be maintained by the Drupal community at large. Topics will include:
- How using web components allows us to offer a single set of components that can be used in a variety of front ends, from popular JavaScript frameworks like React, to Drupal’s Twig based templating engine.
- Structuring components to allow a variety of styling options, while still taking advantage of scoped styles.
- State management and approaches to handling data from a wide variety of data sources.
- Thinking ahead to the possible impact of a community driven design system.
- Learning from similar efforts within the Drupal ecosystem.
- Keys to success for this project, and how you can help.
Brian Perry
Sr. Front-End Developer @ Chapter ThreeBrian is a versatile developer with experience building complex, interactive web applications in support of large-scale localized sites. Recently he has focused his efforts on evolving Drupal front-end development practices, decoupled Drupal, and style guide development techniques and has spoken on the topic at various Drupal events. Brian is a Drupal 7 and Drupal 8 Acquia Certified Grand Master and loves all things Nintendo.
![Brian Perry](/sites/default/files/styles/medium/public/pictures/2018-12/profile_crop.jpg?itok=oEUbNaMX)
LECTURER:
This time. And this is envisioning a design system maintained by the Drupal community. I'm Brian Perry. As I mentioned before, there's a link, a Bitly link to these slides. If you want to check them out or save them for later. Yeah, Brian Perry, I am a staff software engineer at Pantheon. I am a former initiative coordinator for Drupal Decoupled Menus Initiative. That initiative is complete. I live in the Chicago suburbs, so I had a really nice, slow, almost 90-minute drive in this morning. It was great. I enjoy Drupal, JavaScript, and all things Nintendo. Very jealous of seeing a recent trip to the Super Nintendo world. In the world of video games, I recently finished judging by the (UNKNOWN) here, Metroid Prime remastered for Switch, which is amazing and it's my favorite game of all time. And the remaster was awesome. Waiting for the new Zelda game in a couple of weeks. That'll be the only thing I play for a while. And the other completely random video game-related suggestion I have is there is a documentary from this studio called Double Fine who made like Psychonauts and Broken Age.
It is a 20-hour documentary on the production of one of their games. And it's also really interesting from the perspective of just developing software. So cool stuff. I also own the domain web components.wtf. Currently not doing anything with it, but seemed relevant for some of the stuff we'll be talking about today. I am on the internet in a variety of places and would gladly internet with you. As I mentioned, I work for Pantheon. Main thing that I wanna mention is that not all, but many of the things that we will be talking about Pantheon has sponsored some of the open source work for, so I thank them for that. Also, I'm focused on their Frontend Sites project, which can be used for decoupled hosting for Drupal or WordPress, so we'd love to talk more about that. And then for no particular reason after that slide as an individual, I would just like to mention that I don't support hatred. It's weird that I have to say that. Perhaps you could say that I don't have the right to say that, but as an individual, that's my stance.
And if you wanna talk more about this or are confused by this, I would be happy to talk more. So back to the task at hand, the title of this talk is Envisioning a Design system maintained by the Drupal Community. So we'll be asking a number of what-if questions and envisioning a handful of different things here. So the first thing, these are somewhat leading questions, but what if there were a set of Drupal-friendly components that anybody could use and you could use them in Twig and you can use the same components with any JavaScript framework and it was easy to extend them, contribute new ones, change them. That obviously would be wonderful from my perspective. And what if web components made this possible? So here when we're talking about web components, we're not necessarily talking about the JavaScript frameworks like React or Vue. When you explain web components kind of at this level, you've probably already lost. But here we're talking about web components as a set of web platform APIs, three main pieces, custom elements, the Shadow DOM and HTML templates, and we'll touch on all of those things along the way here.
And since this is these are core Web platform APIs, they're not tied to a particular framework. So let's just jump in and look at an example of a Web component. So this is a card component from a project called Generic Drupal Web Components that will be seeing some examples of today. But on the right-hand side, you can see it's just a card, it has an image headline, body text, a link, a very common component. In this JavaScript file here we're importing a JavaScript file and then also a style sheet. And then if we just look at the markup. So this is a code sandbox, just an HTML document in this case. So in the markup, you'll see now we have this GDWC-card element that we can just use in our markup, and we're also passing in a few different properties like the image source headline, body text and etc. And if we change those things, the component re-renders. The other interesting thing worth noting here is that below the card, there's just a traditional paragraph and you'll notice that the card component has its own styling, but the paragraph below it has just the styling of the document, which in this case is nothing.
So it's just default browser styling. But those things don't, in this case, cross paths. So with that simple HTML example, let's look at a few... The same component in a few different contexts. So this is a screenshot of the same card used as a teaser view for content in a Olivero subtheme. It looks exactly the same, except in this case content from Drupal is coming through. And here's a quick look at what has to happen behind the scenes for that. So you need to create a library to import the stylesheet and JavaScript file for the component. And then in the Node article teaser, that HTML twig templates, you basically just can use that custom element like any other markup that you would in your twig template. And you can still do all of the things that you're used to doing in Twig. So we're using attributes. You can use twig filters and things like that and reference content from Drupal. An exciting kind of future Drupal development. Anybody? I don't know if anybody is familiar with the work that's been done recently around single directory components, but that is something that I believe landed in Drupal ten one.
And without going too deep into it, that feature will actually make this even easier. If you just put your CSS JavaScript and your template in one directory, Drupal will just pick that up and make a component out of it, which is really exciting. So this is yet another context. This is the same component used in a JavaScript framework, in this case, Vue. So if we look at our Vue file here, there is a template up top. We're using the same custom element this time statically passing in some values. There's also a completely unrelated component there. And then we're essentially doing the same thing, importing our JavaScript and importing our stylesheets. And again, the card looks the same. So seeing that one web component used in a few different contexts, I definitely think there are some pros to using web components like this. So one, as I've already touched on, is that there are core Web APIs. The different frameworks all have their slightly different APIs, slightly different takes on things.
Some of their APIs change over time. Like for example, a couple of years ago at this point, React introduced Hocks, which kind of changed how everybody approached building components in React. But this is just something that's part of the browser and the web platform now. There is wide browser support for this. That wasn't always the case, but now in all evergreen browsers, especially now that IE11 is dead and we can all dance on its crave. It supported, yeah, in all evergreen browsers. And then there's also the concept of the shadow DOM, which we'll dig into via a few examples, but that really does allow you to create a component that is truly encapsulated like we saw, we saw that same card without really doing much of anything. It looked the same in all the different contexts. We used it. Part of that is the shadow DOM, which is its own kind of allowing components to have its own isolated DOM outside of the global DOM and document. Yeah. And all that really does give you a component that you can write once and use everywhere, even across JavaScript frameworks, which is awesome.
It's just a new HTML thing you can use. However, not without some potential cons. So partially because this is a core browser technology, the developer ergonomics, in my opinion, are a little rough without using a supporting library. So you can write web components using just vanilla JavaScript without bundling anything. But I find that it's more pleasant using a library like Lit. I kind of lit a Google project. I kind of associate it 1 to 1 with building web components, but it adds some things like templating that I've just become used to as a front-end developer, helps you avoid some boilerplate handles, some common things about properties and attributes updating just makes the whole deal more pleasant. Styling can potentially be unintuitive depending on how you use the different features of web components. And it's really just because they introduce features about scoping and encapsulation that were not the way we thought about styling in CSS traditionally. All CSS usually is part of just the global document, so can conflict in different places.
You have to do certain things to scope using classes or specificity. And this definitely changes the game, which requires you to think about things a little bit differently. You know, kind of touched on this in the first one, but because this is a core web technology and is not a framework, it doesn't necessarily have some of the developer experience things that you'd have in React like it doesn't have opinions about bundling your code or anything like that. Increasingly, bundling is not necessary with web components, and I hope that continues. But regardless. And then also this is these components are JavaScript at the end of the day. So for them to be fully interactive and mounted on the page, JavaScript needs to load, which means that there are potentially some server-side rendering issues. That is something that is also improving with the web component spec, but something to be mindful of and we'll talk about that a little bit towards the end. So but I think that on an infinite time scale, these types of browser native components are gonna be an important part of building for the web.
Using components is not something that's going to go away anytime soon. The thing that as I learned about web components I had my doubts about is like if this particular approach to it is the thing that is going to survive. I do think that it's gonna continue to evolve, but I am more and more confident that this is the thing that is going to represent components in general browser tech. However, on a much shorter time scale, I think that all of us will be running into web components either in our actual browsing of the Internet or if we're building on the front end more and more. So your bundle, if you pull down a library from NPM, maybe you're looking for a component even to use in a React project. It may be that behind the scenes it's actually a web component so that it can be used with different frameworks, but it does the thing that you wanted to do and you don't really have to care one way or the other. But I think that over time, more and more of the things that you work with, even if you're not explicitly seeking them out, we'll use this technology.
There's a lot more to talk about related to Web components. I gave a talk in the past at a couple days that was just a deeper dive on web components. There's a link to that if you wanna check that out. There's been other great talks in the community, Andy at Lullabot at New England Drupal camp, I believe, gave another great talk on the topic. So if you're interested, check that out. So going back to more of a actual use case here, what if we made a menu web component for Drupal? So I mentioned previously that I was involved with the decoupled Menus initiative and part of that project was building a new endpoint that also is gonnam be added in Drupal ten one to expose menu data from Drupal in a way that is easier to use on the front end. But another thing that we did is that at a past DrupalCon, we got a bunch of front-end developers together and did kind of like a hackathon thing and encouraged everybody to try to build a bunch of front-end components that consume data from this new endpoint.
So what I wanted to work on, I was just starting to learn about web components. I wanted to see what would it be like if I built a web component to achieve this. So this is that component you'll see on the right-hand side, there's the menu. The styling is intentionally stripped down, which we'll talk about a little bit more in a sec. But, we can expand and collapse the menu within the mobile view because the viewport is a little smaller here, but we can expand and collapse elements. And then if we look at the markup, similar thing where there is this GDWC menu custom element and we can pass in data. So the branding is the title and the header. Perhaps more interesting is that base URL there. So that is the root of a Drupal instance with this menu endpoint enabled. So that's what allows this component to go reach out to Drupal and get the menu data, parse it and display it like this. There's also the menu ID that's the name of the menu. So if we change that to the account menu, you'll see that it gets data from Drupal again.
Since we're not authenticated, the account menu just has a login link, but we'll change it back to mean so it has a little more stuff. And then also there is this theme attribute as well. So that had... that allows some basic ways to affect the look and feel of this component. So right now it's the horizontal theme, but we can remove it. And if we remove that theme, it just has very light styling to make the expand and collapse possible. But alternatively, there also is a... oops that was the wrong one, a theme of Unstyled. And if we do that, it literally just is an unordered list whose styling you can override. So as kind of a first step, dipping toes into the water there, that seemed like a really interesting use of web components, something that could be useful for Drupal projects. So within that generic Drupal Web components project, we immediately were like, OK, how can we build more of these things? But found pretty quickly that some of the things that we did in that initial proof of concept component proved kind of hard to scale.
So the first thing we touched on a little bit with the theming, but what if we wanted to restyle these components? The examples that we'll look at here are all in the storybook for this project, which is on the Drupal GitLab pages at that link, if you ever want to play around with them. But we'll also just open it up here. Alright. OK. Yes. We're looking back at the menu component again that we saw there. And here we were definitely exploring with web components and some of the things that make their styling different, like how could we create a component that people could adapt to the look and feel of their site? So we already talked about the different theme attributes, but there are a handful of other ways that you can affect the styling from the outside. So first off, in this component, we're using the shadow DOM, which means that the styles of this component are scoped to just that component. So there are some exceptions to this, but the basic idea is that styles don't come in and they don't go out beyond this component.
So there are some ways that you can reach in and allow that outside styling to happen. This first one is the idea of a shadow part, which is a new CSS selector, so you can explicitly define a part in the markup for your component and then do something like this part menu level selector here. So there's a menu level and a menu item, and that is what allows us to override either a full section of the menu or an individual menu item to make it ugly pink and dotted like we have there. But basically, you can using that selector if you expose that style it however you want from outside of the component. There also is the concept of slots in web components. So that is basically a place where you can put markup. All web components have a default slot, but also you can create name slots as well that might have a specific purpose or a specific landing point in your markup. So there is a slot for the branding here which essentially allows you to override the entire markup of the header, pass in whatever markup you want.
That markup is markup from the traditional DOM or light DOM. So it means that you can also override the styling of that from outside of the component. So that's another way into it. And without getting too deep into this, web, components are JavaScript classes. So assuming that the code allows this, it's not like a private class or something. You can also extend the class and override it however you want. You can change the render method to completely change the markup, override the styling completely. So that's a pretty big hammer. But you also have a lot of control there as well. And a couple last things. So another option is using CSS variables or CSS custom properties. So I mentioned that in general the rule is things don't come in and things don't come out. The big exception to that are inherited properties in your CSS. So those do go through the shadow DOM They do cascade down from the rest of your document. So for example, things like colors or font styles will do that. But another thing that is inherited are CSS variables.
So you can also set define particular CSS variables in your component that are honored. So like we have one to set the font family here and that allows you to set that value either at the component itself or higher up in the document and have that cascade down. So you could share variables across these components and the rest of your document to do things like use the same set of colors or spacing or something like that. And then the other last thing, which we didn't do a ton of this, but you can also just use classes in your markup as well. So you can define a class and then use the existence of that class in your styles to effect how things look. So obviously, that is a lot. It's many, many options. If you're using this new kind of scoped styling and for a lot of them, it does seem to put a lot of responsibility on the person who's consuming and using the component. And all of them require introducing some particular styling hook or API. So we talked about a lot of them custom properties, classes, shadow parts, and slots.
But the thing that we gravitated towards and I'm seeing a lot of similar web component libraries also do is using CSS custom properties. So, they are inherited and do cascade into the shadow DOM. But the biggest thing from my perspective is that it really does provide a level playing field for the entire DOM. So like I said, you could set it a variable for a particular component and just make it blue or whatever, but you could instead set those at the root of the document and it would be used by anything on that document, including your web components that direct access. But still, you do have to kind of create a system for this and build those things in to allow that level of control. And then one other thing that we ran into while trying to develop a system like this for these components is this project open props and definitely some personal opinion here. But I think of open props as kind of Tailwind, just the good parts. The reason for that is I definitely understand. So Tailwind is a CSS library that uses atomic classes, so they use a lot of classes in your markup to define how things look and feel and not write things in a CSS file.
I understand how that is really useful to developers and how that might help with productivity. For me because I learned how to style things through CSS, it's just not the way my brain works, so it actually slows me down at the moment. So that's why I'm not a huge fan of that particular approach. But the thing that I do think is a really amazing part of Tailwind is its set of design tokens, like its spacing scales and its color variables, and providing a really well-defined system for those things is really amazing. So open props actually is just focused on that piece of the puzzle, a set of CSS variables that you can use anywhere in your application and your styling. And it has things like sets of colors, gradients, spacing scales, animations, media queries, all kinds of wonderful stuff that you can just use to rather than having to invent a system like this, yeah, you can follow. So yeah, I already talked about a lot of this, but it also does have essentially a default set of styles, like a reset style sheet, and it can be scoped to either the main DOM or the shadow DOM for web components, which actually was a feature that they added by our request, which was awesome.
And then thinking of a component library like the project that we've been dipping in and out of here. By adapting this, it allows us to have a consistent way to make those theme controls available to a variety of different components. So if we look back at the card component here, we can see like what that actually means. So here's our card. Similar to what we saw before. That's what it looks like by default. But in Storybook, we have essentially all of the variables that this library now recognizes as controls here. So we can actually pretty quickly really change how this thing looks so we can change the font family. We can change the heading text here. And then let's see, we can make the background, we can pretty quickly get into some kind of ugly things that could be worse. But we can add padding to this. That's maybe too much padding a little bit better. Round out the corners of the card. Give it a drop shadow etc. So by allowing these components to kind of hook into that set of variables, you can use them.
And again, it could be this here is at the level of the component. But if you wanted to say that all of your headings are that color, you could set that to the document and it would cascade down to anything in the document that recognizes it and all of these web components. So really can kind of drastically change the look and feel here. And if we just clear it out, goes back to what it was before. So, to be able to develop a library of components like this that you want to be able to have a consistent look and feel and match some other application really helpful. OK. And yeah, this is just one other example in context that shows how this can be useful a little bit. This is our View app again that we saw before. Depending on how front-end detail-oriented you are, you may notice that the font stack is a little bit different between the card and the rest of the app, and depending on your personality, that might drive you insane. But using that variable, it actually makes it really easy again, to set it at the root and have it cascade down so we can briefly break the whole application, but set the font family and just copy the font stack here.
And then you'll see that that just cascades right into the component as well. And it matches a lot better. So back to some more what-ifs. So thinking again about components that can also work well with Drupal, either in a twig template or outside of a twig template and a decoupled application. What if the components in this library could work with any data but optionally knew a few things about Drupal? So to explore that, we're gonna look at this link component. And to get this out of the way up front, creating a custom element for a link on its own is not very useful. You could just use the link element. So but we do have that. We have a link here that has all of the properties on a regular link href, title etc. But where this gets a little bit more interesting is if you think about a link here in a decoupled application that is sourcing data from Drupal. For example, if you're using JSON API, the data that you get back for a link field is not something that you can just use to immediately print out a link.
So you'll have to do a little bit to get the right data from that object. And then also in Drupal links, there are still some Drupal-specific things like there is I can't remember if this. Yeah, this does have an example of it. So in this data object here, you'll see that there's that internal prefix for internal links and outside of the context of Drupal that actually doesn't really mean anything. So what was added to this link component is the data property here. So you can just pass in the object. In this case, it's the data for a link object, link field in Drupal, and rather than having to specify those properties individual individually, it's going to look at that data object and use it to render a link. So that's the case where having a link element that knows a little bit about Drupal can save you some of that processing and extra work there. So looking just a little bit more closely at how that actually works in this component. So in the render method for the component here, we just check to see if that data attribute exists.
And if it does, we run this process data function, and then when we render the markup, it is just a link element, but we just use the values that are set within the component. So this is the actual process data function and it doesn't do a whole lot but just does a little bit of processing. So if there is a URI, it strips out the Drupal-specific things, so it can give you a link that would actually make sense outside of Drupal. And then for something like the title, if that is in the link object, it just sets that property in the web component. Again, so you don't necessarily have to. And so getting into the data there, that also kind of gets a little bit into just more thinking about a decoupled application of some kind but managing data from Drupal across a series of components. So yeah, what if we wanted to manage our application state across multiple components? So we're looking back here at the menu component that we saw before. And one of the interesting things that that does is you can pass in that base URL and it uses that to actually go talk to Drupal, get the data that it needs, and render out the menu hierarchy, which is nice.
This is a little bit of the detail of what is actually happening behind the scenes. So when the custom element mounts, it runs this fetch data method and takes in the base URL and also the menu ID, the machine name, and it uses that to construct the endpoint that it should talk to. And then it just uses fetch to go talk to Drupal, get the data back. There's some lite error handling and then it parses the results into a hierarchy that can be more easily rendered in the component. So, again, not a ton of code, but nice that the component can handle that for you. But if you start to think outside of just that one component, it doesn't really scale. So if we think about our card from before. For a card, if you have one card that could be one fetch card ten cards, it's ten, you have 100 cards, or an infinite scroll, you're potentially running into some problems. So the solution for that is you want to take the data that you get back from Drupal and store it at some higher level that these components can share.
But how do the components in this library that their intent is to make it as easy to work with Drupal as possible? Like how could they consistently do that rather than embedding that sort of logic into the component like we did for the menu? So at the time that we were trying to solve that problem, there really weren't a lot of solutions for libraries to talk to Drupal APIs or anything with opinions on managing application state like this. Since then there have been some other similar solutions that have been developed in parallel with this library. But we built something called Drupal States. And so the idea with Drupal State, it's it's a node package that is framework agnostic and universal, so you can use it on the server and on the client and it will talk to JSON API and it will pull data from JSON API. But then for all future requests it will just get it from a local data store so it can cut down on the API request that you need to make back to Drupal. And it also deserializes and kind of flattens out the structure of the response.
If you have worked with JSON API, there still is a little bit of Drupal that kind of comes through some things are under like an attributes object. You have to traverse things a little bit if you have reference entities. So this simplifies that a little bit. A lot more about this library. The decisions that were made and kind of how it was built in a past DrupalCon talk if you're interested. But for the sake of this, we'll just look at a quick example of what this actually looks like in practice. So here in our JavaScript file, we're importing Drupal State and then that allows us to create an instance of that's probably a little hard to see with the like. Sorry about that, but an instance of the Drupal state that is our store and we again pass in the base of our Drupal endpoint. It uses JSON API as a prefix by default, but you can also pass in a value for that. And then with the store you can do things like this, await store.getObject. So that just gets a particular object from JSON API and then specify the object name.
So in this case it's node recipe. So what that'll do is it'll make a request out to JSON API and get all of the recipe data back and also store that in our local data store. So if later on we needed to get one particular recipe based on its ID, we can do the same get object call here, provide an ID, But what the library does is it checks a local state first. It says, "Oh, I already have a recipe with that ID," a recipe object with that ID, and I'll just return that rather than talking to Drupal. Saving you some API requests. And again, you can see the response on the right-hand side, which is definitely a little bit more flat, especially if you're familiar with what you get out of JSON API. So that brings us to, how could we use that within a library like this? So, kind of pushing a little bit there. We asked what if we created a Web component itself that could actually source data from Drupal. So this is kind of what that little experiment looks like. We added two additional components a store and a provider.
So the store basically is an interface to the Drupal State store that we saw before. It has a lot of the same properties you can pass in your API base, a prefix, a language, and then that is where the data is stored. It handles going out and talking to JSON API and then within the store you can have one or more providers and those essentially are an interface to that get object called we saw. So it lets you go get specific pieces of data from JSON API. So we have object name in this case an ID for a particular recipe. You can also pass along parameters that JSON API recognizes. So you can include additional data, sort things like that. And then what that allows you is that... so inside of the provider that you can just use an HTML template. It might be a little hard to see, but just a template element. And inside of that, you can use any markup. So it could be custom elements. We see here we have a card component, but it also can be just any regular markup. So we have just some static markup there for the template.
And then also, as you'll see in here, you can also reference any of the data that comes back to that provider. So we can reference the summary field to spit out the summary for the recipe. And our headline right now is static, but we can use the double curly braces, kind of a twig-friendly type thing, and reference the title field here and now we see the actual title of the recipe. And a few other things that this can do. I'll actually remove this static markup for now, but so if it gets a single result back, it'll spit out the template. If we remove the ID here to get all recipes, if multiple results come back, it iterates over that template for every result. So you see here, here are all of our recipes. And then because this template is an HTML template, we can do anything we can do with HTML, including adding a style element here. So we add a few lines of code to style this as a grid using CSS grid. And then because this system recognizes those CSS custom properties, we can also set a few of those to tweak the styles of the cards themselves.
So, that was a whole lot in just in code to be able to get a set of data back just in markup here to be able to display a grid of cards. So, there's a lot of ways that a concept like this could be shared across components. But it seemed to be an interesting way to be able to use this technology to share data from Drupal across a whole system of components. Alright, so we're just about wrapping up. I know that we should have time for a few questions, but also I know that we're keeping everybody away from the school cafeteria. But so given these experiments, kind of what's next for a project like this. Speaking completely honestly, I think that at this point I need to revisit if a project like this in its current state really makes sense. We definitely have had outside contributions, but maybe not enough to really sustain a library like this. And I also have limited time. So wondering from that perspective. But also, given some of the things that we learned here and some of the things that are going on in Drupal right now, I'm wondering if maybe the better focus are things more broadly for Drupal that can make it easier to work with web components or easier to work with these types of decoupled projects in general?
So some of those things are... I've talked about this on and off before in various contexts and you obviously worked on that library, Drupal State, but I've always had the dream of trying to get a variety of different people together to create an actual official JavaScript client for Drupal. And hopefully, I'm gonna finally make a kind of last push to see if we can get some momentum around that. So if you want to learn more, I'll be around and at the contrib days, love to talk more about that. Also in ten one that experimental single directory components really does change the way that you can build with components in Drupal. It doesn't solve all of the problems but certainly does solve some of them. And I think we'll make it easier to use web components in Drupal, which is awesome. And then just in general, anything that we can do to make Drupal more friendly for web components I believe would be a good thing in general. Which brings us to this last little bit related to that, I think something that could be worked on with the community that I think would have a lot of value is trying to solve issues with server-side rendering of web components in PHP.
So I mentioned before that web components are JavaScript at the end of the day. So in the default use case, for it to be fully interactive, JavaScript has to load on your page. However, there have been some changes within the actual APIs for Web components and also supporting tools around it. For a feature called declarative Shadow DOM, all of these web components things have wild names, but that is gaining browser adoption. I think it's already supported in Chrome and Edge and I believe Safari recently and I think Firefox finally has official intent to support it. But basically what declarative shadow DOM is, is it allows you to define a web component in static markup that will render on the page even if JavaScript doesn't load. So as long as you have the server-side rendered markup component, it will still render on the page. There are definitely certain things that you would only get from a progressive enhancement standpoint if JavaScript does load because those things are JavaScript, but you don't have the situation where for example, if the JavaScript doesn't load or JavaScript breaks, the component just doesn't display, which is great.
And that would be really great for Drupal because Drupal is a thing that server-side renders and right now there really isn't a great way to server-side render web components in Drupal. A lot of the current solutions to take advantage of this declarative shadow DOM stuff is all written in Node, so I'm really not sure what the answer is there, but I do think if there was a way that Drupal could also have a similar solution where you can easily server-side render web components that work with or without JavaScript, it would be great for Drupal. It would allow us to take advantage of web components more broadly in Drupal and would also just be good for the PHP community in general. Also do want to take a second to thank contributors to these projects. Be it the menu web component is part of the decoupled menus initiative. We had somebody within the summer of code last year contributing, people who contribute to generic Drupal web components, Drupal State. And if I missed you, I'm very, very sorry and still appreciate your contributions.
And last, what if question. What if the talk was over, but you had questions? So, yeah. Do you have some time for questions? Thanks, everybody. I hope this was interesting.
STUDENTS:
(APPLAUSE)
LECTURER:
Any questions? What sort of things do you want for lunch?
STUDENT:
I've one question, so your definition of what component that you went over with the custom tag custom elements. That's different than single directory components, right? And the definition of what a component is.
LECTURER:
Yes. So, yeah, the question was your definition of a web component that's different from single directory components. Yes. So the way that I defined web components, in the beginning, was browser APIs. That is the custom element, shadow DOM and HTML templates, and then single directory components, what that is in Drupal is a new way that you can define a reusable component in Drupal. Basically, it's called the single directory component. So it's a way that if you put markup CSS JavaScript in one directory, Drupal can recognize that and say, oh, this is a component and then you can with a twig function, render that throughout your templates. So those two things are not really directly related. However, there are ways that I think single directory components does lend itself to that web component use case. The absolute simplest part of it is to be able to have that custom element that you can use. You need to load a JavaScript file and developers who are not as familiar with Drupal like they would have to create a library, they don't know what that is, etc.
Single directory components as I understand it, allow you to just put a JavaScript file in a directory next to a template and it works. So that streamlines the whole deal with web components. If somebody knows how to write a web component, they can do it in a JavaScript file, drop it in this directory, and then they can just use their custom element that they just created with whatever name they want, which rules in my opinion. Any other questions? Alright, thanks, everybody. And I'll be around if you want to talk more.
STUDENTS:
(APPLAUSE)