All right. Welcome to the time to decouple your searches now. I'm Kyle Einecker. If you would like to follow along with the slides you can do so at tinyurl.com. Slash MidCamp decouple search. And we're going to get started. Um, so yeah, as I said, I'm Kyle Anacker architect, the developer. Um, I really recently turned into a full time contractor as of January of this year. And on Drupal.org, you can find me as control a Devel and other places. I'm either ctrlADel or Kyle Einecker and that is the session. Anybody have any questions? Um, no, I have questions for you. So how many people have built search using a search API before with Drupal? All right. Good part of the room. How many people found it hard? Yeah. Most people. Um, how many people were the site owners happy with the end result of your search? For the most part. Okay. Were you happy with the end result of your search? Not. Not so much. Um, do you think it should have been easier for most people? Yep. Most people think it should be easier.
Um, so yeah, we're hopefully going to talk about how it can be easier, um, and how it can be feel a bit more modern. But first, let's do kind of a brief overview of kind of search and search architecture and search pages in general. So in its simplest form, search is taking content from one or multiple sources. If you're a larger organization, putting it into a search index like solar or Elasticsearch, or if you don't have a search provider with Drupal, you can put in the database and then you render it out to a search page. So it's a pretty simple approach. Um, there's a lot of complexity in those, you know, three little pieces. But in general, we're trying to take content, index it so we can search it and then display it to the user in Drupal. What this looks like with search API is you have your content all the way up here on the left. Um, it goes into the database because you're storing your content and then search API looks at all that content in the database and puts it into your search index using processors and fields and whatnot.
Um, and then when somebody makes a request to your search index, search API, then jumps in again to connect to your search index, whether it's solar or Elasticsearch, your database, what have you. And it provides a views integration, which is, I think, what most people are using to build their search pages and kind of leverages the database to ultimately build your search results. And then if you have facets, facet facets is kind of doing its own thing. Like it hooks into search API, but it doesn't build into the view. So you end up putting both the view and blocks on your page, and they both try to get on there at the same time. Um, this is a pretty complex approach for what it should be, something that's fairly simple, right? We have one search index. Why do we have two things. Trying to put something on the page. Why are we using the database when all of our content that we're searching is in the index already? Um, in general, like there's just a little bit of complexity and it's probably unwarranted.
So when you're looking at decoupled search, the idea is that instead of kind of going through views and going through facets and blocks and what have you, the idea is when you make a request, you go through search API and you put the search API response into an endpoint. And if you have facets, you also add facets to that endpoint response. And then on your client side and your browser, you can just consume that endpoint and build your search experience there instead of doing it in Drupal and Twig and PHP. Uh, so with decoupled search, there's a couple key considerations. We are well, when you're decoupling search, there's a couple key things that the search needs to do on the page to feel modern and to work correctly and to not kind of get into some edge states. So you need to be able to load an initial search state from the URL, if that is one of your requirements. It is a pretty common requirement that like, you can save a search query and come back to it and it will work on the page.
Uh, you need to be able to apply remove filters, fast as options, etc. right sorts pager's listing the display type, etc. you need to be able to fetch a new search response, right? If somebody interacts with the page and they go to the next page, or they change the sort, you need to be able to make a make a request and get a new search. And then you need to be able to render that that response, that JSON response into a search experience that the user is expecting. And there's a little bit of client side state management of the query. Right. So you need to keep track of what the query is typically sometimes what some of your elements are kind of displaying as versus what they're sending to the the endpoint. So there's a little bit of state management as far as the current state of the search and how everything is interacting with each other. So that's a couple decoupled search considerations. Next let's walk through the parts of a search page I think there is a search page is understated underestimated for the complexity because there's a lot of unique elements on the page.
Right. It doesn't look that bad until you realize that everything on the page is only on the page once, right? Everything you're building, you can only do once and you're not going to reuse it. Um, so the small elements all pile up and they all interact with each other. So we're just going to kind of walk through what, what you typically see on a search page. National geographic isn't using Drupal. I just happened to Google sites with good searches, and this popped up in one of the listicles. So we're just going to use that as an example. It has most of the elements we need to look at. Um, so the first one is a header search right. So typically somewhere in the header there is a search bar a search icon. And that will take you to the search page when you interact with it. It's not typically functional on the search page itself, but it does get you to the search experience and does need to know where search is. So that's typically part of a search build out. Uh, you have your search results.
It can be either a grid or a list or both. And you can have cards or tiles or, I don't know, teasers, whatever you want to call them. Most of the times there's an image and there's a link to go somewhere else. And sometimes there's icons, sometimes there's a map. Um, and if you're in a fun situation, there's multiple different types of results, right? Where the cards look different based on the result type or the content type. Or maybe you're trying to put your results onto a map, right? So it's a location. Um, we're going to stick with kind of the simple example, right? We just we just have cards for destinations image, an image, a title, a trip type, activity level, etc. this one's not too bad. You have sorts. So National Geographic actually does something a little bit I'm not going to say unusual but but not so common. There is a list. Right. So it's just a list of buttons you can click instead of being a dropdown, which I think is a bit more typical. You have your summary and there's usually or at least for this one there's more than one.
Right. So you get a summary of the number of results you have which is 69 trips. And then you have also what was your search query or results for Europe search. You have a pager. So National Geographic has a load more or show more button that will load more results in. It's also pretty typical to see uh, a pager itself, right? Like one, two, three, first, last, etc.. Uh, and then National Geographic doesn't have it. But I pulled this from another site I worked on. You typically see a search bar on the search page itself. So if you want to change your search query, you can do that right on the page instead of going back to the header search. Um, and typically it will, you know, have some ability to clear your search or it might do an autocomplete, or it might have recommendations when you're typing stuff like that. And then you have your no results. The one that I always forget to do until the very end. Right. Because your search is working and you're getting results. And then you realize sometimes people search for things that don't exist and you need to have a no results page.
So it's a good one to remember. Um, typically you do something like you put a piece of content that says piece of like a paragraph that says, you know, no results found, or you do some recommendations or did you look for or do you need help? Call us, etc. National geographics is pretty simple. It's just a no results. Uh, and then on more complex or more, more well featured searches, you kind of get a how do you want to display the results, right. Do you want a list, a grid, a map. So this is from Craigslist, um, where they have, I think, pretty much every option I've really seen. Right. Like a gallery, a map, a list, thumbnails, preview. Yeah, a grid. I don't know if I've ever seen more options than what Craigslist has, but it's not unusual to see that as well. And then you get into filters and facets, right. So all the options that are typically in the left sidebar or up on top that allow you to to modify your search, to limit your search to what you're looking for. It can be checkboxes, it can be dates, it can be ranges.
Um, I've seen a lot of unique implementations, and the end goal is that all of these are just trying to get you to the content that you want. But in Drupal, filters and facets are very different things. Um, and I've spent the past couple of years educating every project, like all the PMS, all the business analysts, clients, client developers, everybody I've talked to on every project over the past couple years, I've pretty clearly defined what is a filter and what is a facet, because the level of effort in Drupal to do a filter is easy, the level of effort to do a facet is hard. Um, so wherever possible, I've been limiting implementations to filters. Hopefully that will change after the talk today. Um, but when I when we're talking about filters, filters display all the possible options for search. They're not dependent on the search results. So if you're using a taxonomy it's going to list every book or every term in that vocabulary instead of just the terms that are relevant to the search results on the page right now, um, you can select filters to display no results, right?
So you could filter yourself down to a combination that has no content for the for the results. And that's just a bad experience. Uh, filter options don't change based on the search results. So if you do a search or if you, uh, if you do a search, they're not going to change. If you apply a filter, they're not going to change. And in general, that's just kind of confusing because like I said, you can configure your way into a no results situation. The upside is easy with views right. This is what views does that has that whole filter area. And you can quickly and easily add a filter to a search page. Uh, facets on the other hand, display only the options that are relevant to the search results. So you're never going to get yourself in a situation where something in a facet doesn't apply to at least one of the results on the page. Um, and because of that, it doesn't allow you to select a combination of facets that don't return any results. You're always going to have at least one result when you're doing a combination of facets.
Um, it's not possible with views though, right? So it's not baked into search API view integration. You end up having to do blocks that you place on the page with the view, and the blocks have to know that the view is there in order to render. And I've spent many hours figuring out why they aren't rendering. So in general over the past couple years, like when I've been doing search pages, if a client said they need two facets, I made doubly sure that they actually meant they needed facets. And they didn't just want filters, and if they didn't need facets, I added a couple of weeks to their estimate. Um, so that was a bit of a tangent. Um, but it is good to know the difference when you're working with views and search and facets and filters and all that. Um, let's see. So why decouple your search? Well, like I said, you have all these little unique elements on the search page. And with the current approach, with Ajax, you're managing a bunch of small independent HTML templates that all need to go back onto the page and replace certain parts of it, whereas with decoupling.
You're managing a single endpoint and a JavaScript library that's going to render everything out from that endpoint itself. So it's a little bit of potato potato. But I personally don't want to deal with an Ajax response that is replacing ten different things on the page, because I found it to be pretty inconsistent. Whereas the JavaScript will typically render as you expect, regardless of kind of the response you get that and it's it's a lot of twig templates to manage with a lot of complex interactions. So you end up having twig templates that you know are dependent on the state of the search, but they don't necessarily know what the entire state of the search. And they might be dependent on other templates and what they're doing. But once again, they might not know about them. So right now, like the state where we have a twig template for a facet and a twig template for a search input and a sort, and they're not really connected together, it can be challenging. Whereas when you're decoupling, you get that single endpoint response and you know the entire state of the search everywhere.
Uh, another reason. So users expect a smooth, fast experience without page reloads, right? So they expect that when they click a facet that the search results are going to update in a timely fashion, a performant fashion, and that they're not going to, you know, lose their lose their spot on the page that everything on the page is going to rerender. At the same time, if your elements are kind of coming in one at a time, that's, that's, you know, just as confusing as a full page reload. So users expect that when they're doing search, they're going to be able to find what they want quickly and that they're not going to kind of be tossed around on the page, or that they're not going to have to figure out how your search works to get get to what they're looking for. And that is really a lot easier with JavaScript on the client side than it is trying to manage. Like I said, all those individual HTML snippets from the server. Another reason. Searches and interaction. Heavy experience with a lot of client side state, right.
So there's a lot of different pieces, a lot of different elements that we were talking about. And they all kind of interact. A user can click one button, and the entire every element on your page has to, you know, rebuild itself, rerender. So really, if there's any perfect example of what JavaScript is meant for, it's search because you want to kind of react to what the user is doing and you want to provide a good experience, and you want everything to kind of know about each other so that everything can seem cohesive and as one element, even though really we're dealing with a lot of small individual elements that all have their own concerns and finally, performance. So like I said, like we looked at in the diagram with search API and when you're using views, you're going back to the Drupal server and you're doing a bunch of twig rendering. And there's too many different combinations to cache those results. Right? So pretty much once the user is doing a search, they're hitting an uncached response or an Uncached page.
And that's not the fastest thing in Drupal, right? It can be pretty slow. Um, the other thing is that search API by default calls the database, right? So even with your content in the index, and even if you set the, um, like the your let's see, your search server has to explicitly support this. And when it does, you can pull content directly from the index into your search result. But if it doesn't, search API by default, loads all of your search results from the database like the most recent entity, and uses that for your search results instead of just using the stuff from the index itself. So from a performance perspective, you're losing a lot of the benefit of using a search index because you're loading content out of the database anyways. And in general, database calls are bad for search performance. You want to avoid them if at all possible. There might be times where you need to like if you need to do access control or like dynamic stuff based on a user type. But in general, for just a general site search, there should be no reason why a search has to go out to the database to return results.
It should all be in your index and that is going to be really, really fast. All right. So I've kind of sped through a lot of that because we're going to go to a live demo here. But before that, um, here's just some search considerations that I came up with off the top of my head over the past couple days. These are kind of things that, you know, I ask myself when I'm building a search or I'm, you know, building out reviewing designs for a search. What was the initial page load speed as we were talking about, like performance wise, are there 500 results on the page? Is that going to be a concern? Do I need to load in like 100 images, stuff like that? Um, we need to be able to load the previous search URL, which comes with search API. But if you're doing a custom implementation, that's a consideration, um, response time when applying filters. So if you've written a bunch of custom code around your search and you're running a bunch of PHP that is doing a bunch of processing every time a filter applies, that's going to affect your response times outside of just, you know, only using the database.
You also need to make sure that you're not doing too much PHP coding or too much customization with PHP and your search response, um, how many HTTP calls are needed? So if you're decoupling, are you making one call per element on the page? That sounds terrible. Are you making one call for all the elements on the page? But then how do you share that across all of your different elements and make sure that they all know about it at the same time? Uh, what actions need to reset the search? Right. So if you have a search bar on the page and they enter a new search, does that clear your facets? Um, if you apply a facet, does that take you from page two to page one again. So stuff like that. Does the back button work. Right. So if you if you're updating the URL and the facets and you're clicking facets and you're building a bunch and the user clicks back, does it work? Does it redo the search or do they just stay there in the URLs updated, but they're still seeing old results? Uh, how many different types of content are indexed?
Right. So in a site search there's typically somewhere between 3 to 10 different content types. And they might all have to display the same even even though they don't have the same fields. Or they might need it all displayed differently, even though they have a bunch of, uh, similar fields. Do all the result types display the same? Yeah. So I kind of got into that one. Um, they're all content and filters available directly in the index, or do you need to do some type of processing or call out to a third party API in general? Just how confident are you that everything you need for the search experience is in the index? Um, translations always adds a bunch of complexity and I forgot to add after that multi sites. So if you have multiple different properties in your search index and you're searching across, you know, a knowledge base and a site and I don't know, a product documentation page or something, you just want to make sure, um, that that's all accounted for in your searches. And that all makes sense.
Is everything in the index of valid result or is it a subset. Right. So sometimes you have stuff in your index for a product search, but you don't want that product search content coming up in your site search. Right. So you want to make sure that, you know, if everything is an index is meant to be on your search results, or if it's just a certain set of it, um, as any of your content access control or gated, because that could make search a lot harder. Uh, because you suddenly need to know a lot about the user, and you need to process all the results for access control. Uh, two result fields change based on your user I pricing. Right. If you're in a B2B scenario and you're doing pricing in a search display or a catalog display, typically you're going to have custom pricing involved. Um, or even if you're just running a discount rate, it can be like a temporary time limited discount. And that will change the pricing. Uh, those that you write, does the UI always accurately represent the the search state?
Right. So when the user is clicking around, can they get into a situation where what they've clicked does not represent the results that are actually seeing? And I've actually managed that quite a few times with facets and views and Ajax where like I click things and they look right, but then you actually go looking and they're not right. So that's a tricky one. And you just want to be aware of it and make sure you're searching for it. Um, and as we're talking about a little bit earlier, is a search query hitting the database for only the index. So this is a long list. And this is a list I came up with very quickly. There's many other considerations as well. And I think there's a lot of them that don't really need to be considered. Every time you do a search. Right. A lot of these can be just crossed off with a good default search implementation. So that's why I wrote a module called Search Web Components. And that allows us to or the goal of the module is to make building search modern search experiences easy and Drupal for 90% of use cases.
There's too many searches where a designer or a client has an opinion about one specific part of it to support all searches, but 90% right if you have a search bar. If. We have checkbox facets. If you have a list of search results, that should be easy. Um, and if you are kind of in that situation where you're doing something unique, it should be easily extensible so that you can build on top of the elements that you don't need to customize, and just customize elements that you care about or that are unique. Uh, so Search Web Components does this by providing a set of web components that build on top of search API decoupled, which provides a decoupled search endpoint for query results. Um, all the rendering for search web components is done on the client side using actual custom web components. There's an asterisk there because there's there's a bit of a workaround for results where we can use view modes instead. Um, but in general all the rendering is done on the client side. Um, it has very good support for facets.
It makes one request to update all of the components. So there's a shared state element to search web components, where all the components kind of look at the same response to build their, their UI, uh, as built on top of lit, which is a library for web components, and it uses lit context to keep track of that response state, as I was saying. So you can think of lit context as very, very simple state management. Um, it lacks some of the nicer things from actual state libraries, but it is a good place to just put things and let children know when, uh, or let subscribers know when things change. And to support. The easily extensible option is published as bundled JS and TypeScript, um, to npm as Drupal search web components. So if you want to just include it on a page using a CDN, you can do that. Or if you want to extend it, you can extend create your own web components and bundle in the default ones through TypeScript. And it should all just work. All right. So now we're going to see a demo of search web components.
But before that um, here's kind of the things that I'm trying to check off with the module from that list of considerations. We're trying to get rid of everything that's not site dependent. Right. So the stuff here, the stuff that's left is more site specific or implementation specific. And everything that's checked off should just generally be handled by a search web components. Right. So like your performance by default, um, how all the elements interact with each other, how how many responses you're making, how the response is made, how state is shared, and all that should always be handled out of the box. And all you should have to do is build a search page. All right, danger zone time. We are going to a live demo. Um, and it's not just a live demo. We are going to do a Choose Your Adventure demo. So I'm going to start us off by setting up the search index. I have a local Drupal site here. Um, it does have a search right now because it is part of the umami demo for search web components.
But we are going to start, start clean. We're going to start building new page, build a new search. We're not going to use anything that's here besides the search index. So I have set that up already because I don't think anybody needs to see me configure a search index. And for reference we have our content index that's 39 pieces of content in it. And we've got a bunch of fields indexed as well. So the first thing we need to do is go to search search API endpoints. This is part of the search API decoupled project. And we add an endpoint. And we're going to call it demo. And we select our index. So we have a content index. And we now have an endpoint. And the endpoint contains some configuration for kind of default I'll make this a little bit bigger um some default settings and some you know what to include in the responses etc.. So we'll kind of go through all these. Our index will search all the fields. We're not going to exclude any fields from the response. The default page limit is ten.
The page options. Oh scrolling uh the page option like the per page options. We'll leave this for now because it's handled somewhere else. Our default sort is relevance, but you can choose any field you want, and you can choose the default sort order and a parse query mode. So we're not going to touch any of these, but they are all here if you need to configure them for your search. And then we get into some some custom form stuff for search web components where we define the sorts available. We won't touch this right now. By default there's a relevant source available, and by default there's a ten page size for the pager available, and there's a list display available. And result mappings will come back to in a bit. But this is how you configure view modes. As results instead of JSON, but for now we'll click save and then we will go to content and we will go create a basic page. Um. Well. And as part of Search Web Components. There's a couple submodules for layout, block and facets, and they're all turned on right now.
So we'll add a section. There's a special search section that needs to be used. Um, as you can see, I want it to be as flexible as possible. So there's like 20 regions available because people need to group things up weirdly all the time. So I figured why not just give give all the options. So we have like three on top, and then we have a two column which has like five on each side and then three on bottom. And if you need more than that, well, you can create your own own layout. All right. So now that we created the special layout, there's some fields some configuration. So we're going to choose our endpoint which is demo one we just configured. You can also just point it at any random URL right. So you could do an external site um endpoint as well. But for now we'll just do use the local one for demo. You can include additional search parameters. So these are hidden from the user but applied to the search every time. So if you need to do like a filter that's always there, you can do it that way.
Uh, our default results per page for this search is ten. Still, our default result display will be list. We do want to update the page URL with the search parameters when we're searching. And there's a nice little built in feature, um, for mobile because you always have that button to display the filters. So there's a special region in this layout. The third one on the left, I believe, if I remember correctly. Um, yeah. The third section on the left will contain itself into a dialogue on mobile based on the breakpoint you configure. So we'll set this to like 750 or something. We'll look at that a little bit later. Um dialogue closed configuration stuff and column widths. Let's go like 33%. All right. So now we have all of our regions. Let's add search results. So everything all the different elements for search that are provided by the module are provided as blocks right now. So in here we have our search components. And these are all the different elements available. So I'm going to add in results.
Click Display Title and we have results and then we'll add another one. Search input. So there's some configuration like what is the button label text, the placeholder text and the remove or the clear text. I'll click that and we have a search experience now. So right now it's just rendering JSON. But this is a functional search experience. If we type in pepper we get a different set of results. And that is the stage set. So who would like to add something or suggest something to be added to this search?
>>:
Can we display only recipes? Only recipes? Um, yes. So if we go to. Let's see. Remember this API slash demo? Nope. API slash search. Slash demo. There we go. So this is the full response. Um, we have our search results and we have our sorts, etc.. So what I'm looking for in here is the field that tells me the type. Type. Yep. So if we only wanted to do like, a recipe listing, we could go into the layout and we could configure the section and we could do type equals recipe. And that's going to be added to every, every query. This is kind of like contextual filters and views. Um, just a bit more manual.
>>:
You need to put a question mark at the beginning. Helptext. Yeah. It said, it said that's just so people kind of understand the concept. It doesn't technically need it, but I'll add it. Yeah. And then we should only get type recipe. Now, um, to make this easier, what we'll do is we'll add a summary. So we have our our result summary and we'll do probably the one I've typed in before at start to end of total. So we can see how many results we have. So we have ten right now. All right. And if we remove this again. We have 21, so that is working. All right. What else do we want to do.
>>:
Can we expose the type filter. We can indeed. So to do that we need to well type facet not filter. Um but we need to configure a facet. So this is the one I already have configured. We'll ignore this. Down here we have our demo facet source. So we'll click add facet. Choose demo. Um choose the type filter I can find it. There we go. Content type, and we'll name it type. Except it's not going to like that because there's already a type one. And then there are four different facet types provided by search web components. Check box A dropdown HTML for those times where you need a custom HTML style. Because styling a select field is really, really hard. Um, a button and a dropdown. So drop down is just select drop down. HTML is JavaScript that looks like a select or functions like a select. Uh. So we'll do a checkbox and there's a bunch of options here. We could use radio inputs. We could do a soft limit. Um we can show the amount of the results. We can make it collapsible. We can show the title of the facet.
And then everything else is kind of just more normal search API facet configuration. Most of that is still fully supported. And we'll click save. So we have our facet now. Now we need to go back to our page. And we go to layout and we'll add it, add it to the sidebar here, the special one. And in our search components we have a facet checkbox. And we use our index or endpoint, we choose our facet that's configured as a checkbox. And. Live demo time. Why? What's going on here? Content demo type. There we go, there we go. And I believe there's not going to be anything because we still have that filter. So Chris we're going to remove your filter. Sounds good. All right. If I click save, do we get something? There we go. So we have our type facet which has recipe article and page. And it collapses because we configured it to be collapsible. And if we click it 1 to 10 of ten. 1 to 8 of eight, so it's all working as expected. Yep. We had to sort through the results. We can indeed. Um, first we should probably add some additional sorts though, because we only have the one.
So I can go to our endpoint. So this is kind of a customization that's part of Search Web Components. In here we have this text area where we need to list the machine name of the field. The order we want to sort it in and then the sort label. So I happen to know there's a title field. So we'll do title and then we'll go A to Z. And we'll go ascending A to Z. And we'll do title descending Z to A. So those will be the variable sorts that are available for this endpoint. And now we can go back to demo and our layout. And we can find our ad block. I will just put it up here. We'll do a sort. Um, and there's a couple of different display options. So select list or HTML. We'll go with select for now. Um we can give it a label. We can give it a label inside the HTML select element. So that's a special one for like when you're doing HTML select accessibility stuff. Um and then we have our sort. And one of the cool things I've noticed is that this is mostly functional inside of Layout Builder itself.
So I can come in here and like change things. And the preview actually like is functional. So I found that pretty handy. Um all right. So we have a sort. Now we'll click save and it will be there. Paying bills. Want to add anything? James. Oh, Chris. I was just going to say. Can you actually render the items? Yes, yes. So by default we display JSON. It's ugly, but it tells you that there's results there, right? It works out of the box. Um, in order to display items, there's two options. You can create a custom web component to render them using your JSON response for the data. Or you can map them to a a rendered HTML field in your response. So right now in our response we have a rendered item field. And that is rendering a teaser for each content type. So what I'll do is we can go look at the search configuration for that.
>>:
Where does that come from. Is that stored in solar. Yeah. So we have our content and we have our fields and we have a rendered HTML output field added for rendered item. Um, so I think we have two actually we have one to search on and we have one just for, just for display. So we're going to look at the result one. And you can say we have teaser selected for all of these. So this is our rendered item I might have grabbed the wrong one. Not that I'm looking at this. I probably want results. So I want the result field. And then we're going to go to our endpoint and um search API search API endpoints. And down here this is where the mapping happens. So this is results mapping. So you can point it at a field we'll point it at. Actually we don't need to point it at any field. But we could point it like type right. So if we want to change the result mapping based on the type of the content, we could do that. And then you have to add a mapping here. Default will be the fallback if no mapping is match.
But we could just do one for now. So we could do like uh a recipe. And let's see I've described what's needed in the helptext. So there's a search result element rendered element that's provided by the library. And this will just render whatever HTML is passed to it. So we're going to use that element. And then the settings for this we need to provide a field to look at essentially in the result. So we're going to tell it to look at the result field. And what we should see now is only recipes are rendering HTML and other content types are rendering JSON. We'll go back to our search. So you do that for each content type in the end. Or you can just do it for the default right. And then it would be all of them. But if you want some different mappings for different content types. All right, let's sort by recipe and it's not working. You didn't actually set that type. Thing talking about. Oh I didn't I didn't hit save on that. You didn't. Well you. Yeah you didn't actually set that setting.
That would help wouldn't it. Yeah. It needs to know what to look at. Thank you. Chris. You got it. There we go. So now recipe. It's just a real simple title and read more. But those are coming in as HTML and all the other ones are still still JSON. So I don't know why fastest does this by default, but it like moves things around when you check things to the bottom. It's really annoying. Um, so yeah, article still there is um, we could go play with it, but I don't think we need to. Um, what else do we want to add? Display them in cards. Okay, so that is a bit of work because you have to do a grid. But we can do that. We can go to the edit on the demo. So this is kind of the display type if you want to do a list or a grid. Right. Because a card is really just a view mode if you want to do a view mode. So we can do grid here, and then we'll add a select field to choose that. And we'll also add because with this key you can kind of do the type or the value. And then a dash for the display type.
So we're going to do articles and grids should also render. Um. As HTML. And then I have some special HTML already prepared for this, because it's part of the demo module. Uh, that's an advanced one. Oh, here we go. We're going to grab this, and we are going to put it up here because it's already included. So this is some styling, uh, that forces the results into a grid, some basic CSS that makes them 300 pixels wide. Yeah, something like that. So we're just going based on we're targeting the element. There will be a unordered list in there with a grid. And we'll go from there. So now we have our display option. We have a mapping. We need to add the the actual control. So we'll add that up here. Let's go down to our search options and result display switcher. So not safe. And again, it's a possibility. I did not. You know, this is just kind of a good thing to do. All right. Save. And now we should be able to save this. So we have our list in our grid and our custom CSS to make the grid, um, actually a grid.
And it worked ish. I think some of the content is too big for the grid because we have the. Okay. Um, but what we do see is the articles are actually rendering as HTML now because we're in the grid. Whereas if we go back to the list, articles are JSON. So there's a little bit of work to get something like a grid, but uh, fairly easy to set up as far as functionality goes. Would you also have to go to like the. Search index to tell it to have the rendered result be the card. Yeah. If you if you wanted a different list versus card like actual HTML, you would need to index both of them.
>>:
Oh yeah. Yeah. All right. Anybody else? Anything else we want to add?
>>:
Tag names. What? The tag names. Tag names? What do you mean? So tags are just had identifiers, right? These know inside their fuel tanks. That way you can show like, little badges. Oh, yes. Um, so the tags are I think they're actually just tags and umami. Um, they are also a facet. So we'll go configure that. And actually we're going to steal the one. We're just going to clone the one we already have configured for time. We don't need to configure a facet again. Tags. All right. So this is going to be a checkbox that's going to show the amount of results. Um show the title. And this has a hierarchy that I put into it for the demo purposes. Um so we'll see a hierarchy and then processing results. We've set it to transform the entity ID to a label so that instead of seeing the IDs, we'll see the label in the facet. So we'll save that and we'll go back to the demo and add that to the page. Each box. No, I should probably figure that out. Why don't you like the default? The default was fine.
All right, there we go. We'll save it so we get a better view of it. And there we go. We have our tags. And there's a hierarchy and the vocabulary. So we have hierarchy plants. We get nine. If we go down to mushrooms we get one. Or I guess we still get nine because it's more there we go. Now we're down to one. Yes. So not really a question for the demo, but. How to use module in general. Suppose you're using a theme based on a design system, and maybe that design system not only has twig and CSS, it also has its own JavaScript. How hard is it to get the two to work together? Um, can you repeat the question for the recording? Yes. So the question is, if you're bringing your own design system with a bunch of twig and HTML and CSS and JavaScript, etc., how hard is it to make this module and the design system work together? Right? Um, so in this case, you're going to have to bend to what the module provides. They are web components. So the markup is locked in. You don't you don't have any ability to kind of really customize the HTML structure of each of the elements.
But you have full the full ability to style them. So all the CSS, like they're all open web components. So CSS from the global page will apply to them. But you can't change the structure of the HTML itself within the components. So you'll have to kind of build your design system around that. And there's no way to override it or modify it. Um, you have to fork the module in order. Yeah. So you would have to use that npm package I was talking about where all the source TypeScript is published, and then you'd essentially be writing your own components. So you could do that. And the components are meant to be, they are written in such a way that you should be able to just override the render result, and the functionality should still work. So it shouldn't be terrible. It shouldn't be like a full fork, but it would be a lot of work for sure.
>>:
Could you extend the web components to override them? Um. Within TypeScript? Yeah, that's that's what it is. So there's a bunch of, like, internal functions where it's like render or get options, apply options. So like you can kind of override the parts you need and leave everything else in place. Um, but it's still a lot of work. Yeah. Because there's just a lot of considerations when you're, you're building components. But the goal is that the structure for these is pretty well known. And you they should work. Like I said, for most use cases the structure should just work. And if you need to customize your design system a little bit, it's probably probably worth it. Um, along the same lines. So I want to make sure I got this in. You might be questioning because this is very, very integrated into Drupal. Is it really decoupled? Right. We've seen in Drupal, but can you take it other places. And the answer to that is yes. Um, so I've worked up kind of cooking show style. This HTML page is just search dot HTML, and in it we're including including the JavaScript for the module from Unpackage.
So from the CDN, nothing from Drupal itself. And we've got some HTML, and we're including the components on the HTML page and the configuration for each of the components. And that's what we're doing in the blocks is we're just configuring properties and attributes that are passed to the web components themselves. So everything you can do in the block interface, you can do just in straight HTML. And we've kind of got a similar search where we've got our results, our dialogue toggle, our facets, um, our search input, our applied facets, results per page, etc., a bunch of components. And we can open this up in the browser. And it works just the same. So anywhere where you can put JavaScript in HTML on the page, you could put this search experience. And one follow up question on the extending the components or. Yeah. So if you choose to show a view mode it's going to use the HTML and our twig template basically. Yeah. The first time it gets sent to. Yep. Solar. And then when I retrieve it, it's going to still look the same.
Yeah. We won't have any JavaScript. No JavaScript. But that's okay. Yeah. Okay. Um, yeah. If you need something a bit more complex, then you would need to start building your own custom components to render the results out of the JSON itself, which is probably going to be the primary like customization extension point where you extend, you use the npm package and you use all the default components, and you just provide your own result display component to map your content so that you don't have to index HTML like that. All right. So yeah this is truly a decoupled solution for search. Um, trying to think if there's anything else we need to cover, I guess. Any general questions? Yes. Uh, how hard would this be to integrate with.
>>:
Like, um, like the the Oliviero drop down, um, you know, top search and or does it, could it, could it work with the like, like autocomplete module or something like that. That would provide those kinds. Of autocomplete is on the list for integration. Um, I'm not familiar with the Oliviero search bar. It's just I mean, it's just the built in for front end search, uh, theme. So for autocomplete in the header search, you're going to need to use the custom component that talks to the endpoint. But for just a search box as like as long as you can point it to the page and it can put the right query parameter on the URL, it should work.
>>:
A logistical question. So given what we've learned, is the time to do a couple year search still now or is an hour ago? Um. I mean, it was probably a couple of years ago, but now everybody can do it, and now everybody in the room can do it because, you know, the module exists. Yes. So suppose you're using a hosting provider who guards access to the solar server so that it can only go through Drupal. Yes. Um, are there any options, any way around that, or do you just have to use a different solar provider? Uh, this still goes through search API. So it's a custom endpoint that uses search API to get the results. So you're still good there? Um, so everything within search API and facets that's still all works the same. The biggest difference is that the front end is an endpoint and not a view. Yeah. And so there's still full support for like you could use solar or Elasticsearch or whatever search provider works with search API. You could write your own hybrid component just to use that endpoint and do whatever you like with it.
Yep. Yeah. Yes, I was wondering more about the rendering of the results. I definitely less experienced with like, web components. Yeah. And so you said that you can use like the. Content view modes. Yeah. So that's what we're doing right now. Um, we have a rendered HTML field and. You know. I like gin, but the menu always disappears on me. Uh, so in our index, we have a full HTML rendered item field called result. And this is configured to use View Modes teaser for all the content types. Um, so when you index the content search API will render the content as this view mode and put it into this index field. And then in the results in the endpoint here we have that that HTML. So if you wanted to go full Craigslist and have all the different ways that you would want to view your content, you just need to create a field for each view mode and render out those results. So you shove it all into the index. If they're all different enough, yes, you might be able to reuse some of them. Yeah. What about like search index highlighting.
So you know I searched for recipe. Yeah. So I was working on that recently. Um, there is some custom code that's needed there because search API returns that as extra data. Um, and you just have to hook into an event to map the extra data to the actual results and replace it. But it is possible, and it does still work with like 20 lines of custom code and an event subscriber. So yeah, there's still some stuff like that to figure out where search API is kind of doing things in an assumed way, and something else picks it up later. Um, versus just putting it into the results like you might expect. Okay, just one question. So like the the module you have on dawg is like an alpha. Would you say it's ready to, like, use. Or for basic. Searches? Yes. Um, the thing that's blocking release right now is mostly autocomplete. I want to get that in there and tests. So I need to figure out testing for the web components themselves. Um, because there's a lot of interactions that I don't want to be breaking things once I tag a stable release.
But in general, the architecture and the approach isn't changing. Like I've used this architecture on other production sites with different backends. Um, it's just really tests that are blocking it right now. And that being said, it is alpha. I do occasionally break things and that you might have to go click save again. Um, as I'm restructuring config, but I haven't done that in a while. So it is alpha. Um, but if you're just doing a basic checkbox search search box results sort search, everything's there. Is the auto complete? Is that dependent. On like solar or Elasticsearch like capabilities there. So it'll probably be built on search API autocomplete. Um, so whatever that supports will be what is supported by the module. And if you want to build your own, you'd have to go build your own, because once again you can just go do that. Is there a did you. Mean functionality in search API or is that. What like. Did you mean like if you. Spell dog. D u d o u g or. Something like. Did you mean dog?
Um. I haven't looked at suggestions in search API in a while. I think that would be another element in the web component module itself. Does does the search API autocomplete handle ngrams on its own, or is that something you need to like work on yourself? I don't know, actually. Um, and also, wouldn't it be, I guess, an area of concern for the component itself, because it would just be it would. Be in the other module. Yeah. Yeah, that's one of the nice parts is I don't have to worry so much about how the search works sometimes. Um, if it's in the result, it's in the result. If it's wrong in the result, then it's the other module's module. Separation of concerns. Yeah. All right. Um, I think I have one more slide here. Yeah. So if you're interested in getting involved, the module is Search Web Components on Drupal.org. I will be at the afternoon unconference and then working on search web components is also a contribution day event. And I'll be hosting some stuff. Um, if you just want to come and set it up on your site, that would be helpful for me.
Or there's a couple issues in the issue queue, or if you just want some more information. And then there's the search channel on slack that's really big. Um, if you don't want to message like 3000 people for, feel free to DM me as well on slack if you have any questions. Yeah, thanks.