 Welcome to Making React Paragraphs. Bad Camp October 22. My name is Mark Cassius. I'm a Drupal Tech lead at Canopy Studios. I live in Albuquerque, New Mexico. I plan a band. No one reads bios. No one cares. I have Twitter handles. Canopy is hiring. If you're looking for a great job or you're using work wherever you want with some wonderful people like myself and Ann and Sean who said he was going to be here but is not. It's a nice company. We do a lot of fun work and I recommend it highly. Go to canopy.com and get a job. I use the same slide so never mind that. I also do work for a thing called greymuscle.org. I use money to help homeless elder dogs get adopted. Feel free to go to greymuscle.org and donate. I also am in charge of upgrading their site from D7 to D9 but since I do it for a living it's a very slow process. So it hasn't been done yet. I've been using this slide talking about my upgrade to D9 since D8 was starting. So I got that going for me. This is my dog. Her name's Drew. She's my pal. I'll let you get the joke on your own. Alright. So we're going to be talking about decoupling, progressively decoupling React apps into Drupal. When I started this as a training I just kind of wrote a bunch of notes and we did it on the fly. So for this case we're going to do it in an hour and we're going to do it in kind of a slide demo. So there are slides. I will share them out later and they do work I think. A couple of use cases that we've done this with at Canopy Studios. There's a company called TR Electronics. They did a product search and that is a React app. Basically the use case for that is they have all their content in Drupal and then they have one small area that's a React app that you search for those products and then you get the ones that you want. It's very interesting on this one because they have just part numbers as their description. And everybody is supposed to know what those part numbers are and apparently they do. I tried to add more description to it. They're like no, no one will care about that. Also we did some work with a local airport and did a flight tracker. We hooked up to their API against the flight tracker using React and then pulled that into a block or I believe it was a paragraph as well. That way you can get updated information while you're looking for your flight. And finally actually the very first time I did this was with another company, weather.com. We were using Angular applications instead of React but we were decoupling that and that started the whole decouple days. Oh I should have had a slide of about decouple days. Through this whole process we started doing decouple days in New York City. This just came to pass in August, last August. Where we talk about not just Drupal, not just CMSs but also how to decouple the sites using Gatsby, using Next.js, everything. It's very interesting if you're interested in this, go to decoupledays.com and then you'll see last year or this last one that's just passed. Alright, so first question people always asking is where do you put this? Do you put it in a custom module? Do you do it as a theme or do you do it as a library? If you're doing a custom module it's really good for blocks because blocks are encased in a module and you can just push them in that way. After we go through my demo, if we have time I will actually create a block because I didn't think I'd fill the entire hour so I thought that would be a good way to finish it off. Another thing you could do is in a library and that's really good if your React application is shared amongst other things. You can make that a composer object and then put it in the libraries area. The only problem with that is that you have to still modify your theme or module to know where that is using the libraries. So that's very good. So most of the time I put them in custom themes because usually JavaScript is in the theme realm and since you're at this JavaScript I always do it that way. I'm going to do a quick demo on creating a paragraph and a theme. The first thing you do is I've created a custom theme called myCustomThing. Just added a folder, JavaScript, templates, that's something that you're going to need and I'll show that later. Of course you need an info.yaml and then you're going to need a libraries.yaml and this is the base of the theme that you're going to need. First thing you want to do is you're going to want to create, this is where the pointing of my pointer would work, you're going to want to create a small folder inside there called whatever you're going to want to put in your call it. I called this one the app thing. You'll notice that it generated based on this, go back, go back. First thing you want to do is do an npm init and what that does is it creates a package.json which makes it an npm package. Then I did an npm install on dev of babble and webpack and it's pretty much babble and webpack for dev dependencies and if you look down towards the bottom, so on the left is the folder structure, on the right is the actual file itself. Down the bottom is the dev dependencies and then in the middle there you see the dependencies of react and reactdom and that's pretty much all the things that you want to have. A lot of people start their applications with a create react app and that is going to give you too much stuff. A create react app thinks that it's going to be the single page and react is going to be the only thing so you kind of want to piece mail it together instead of doing that. Next thing you want to do is create a webpack config. Webpack is a task runner and basically it does a bunch of little tasks for you and then bundles everything up for you and this one basically is doing just the babbling which is all you really need to do on this because the react app will build on its own but you want to kind of add that in there and that's kind of a default one and like I said I'll share these slides once they're done. One thing I forgot, speaking of babble, on the package.json you actually want to add the babble presets on there. Fortunately that line there of IE greater than equal 11, we don't have to worry about that line anymore, do we? So this is what you get when you copy and paste a lot of stuff. Anyway so that basically makes sure that the babble is a thing that converts all react into just generic JavaScript for you which is really nice to do. Next thing you want to do is create your react app and this is a very very basic react app. It imports react, line 1, line 2 imports render from react dom and then lines 4 through 9 creates an object called app and then it just makes an HTML and just creates something. You can do anything you want in there, I went with very very simple. Then the bottom line is the one that really matters, the render, because basically what it does is it says okay take app and then stick it in wherever the query selector of my react target ideas and what that will do is that will create the react app for you and that's as generic a react app as you can get. Next thing you want to do is create a template that basically gives the idea of my react target and then you'll notice that I put it in templates as a paragraph dash dash react target HTML dot twig. Basically all my paragraphs that are going to be called react target are going to just output this and it's funny as I put content in there but frankly there is going to be no content and I'll show you that later. If you're big on using attributes you want to make sure you do it without ID and then set the ID yourself so that's all you need for your template. I lied but I'll show you why later. Next thing you do is you build your react app and that's running MPM build. Once you build it you get this disk folder and I forgot I put that fade in there so it kind of freaked me out. So that disk folder actually takes a bunch of stuff and then it actually has the bundle of the app bundle JS which is your configured application that is at the end of the day going to run. Then you need it as libraries like I talked about when we're just putting a thing in the libraries you need something to point at and this if you update your custom thing libraries YAML and you're just pointing it into the JS react app thing disk app bundles.js and you're going to have a good time. Next thing you want to do is attach your library of course and that's the one thing I lied about when I said that's all you need for your template file you need to attach the library. You can do it with custom code and there are many ways to attach libraries but thankfully durable templating system has a nice function that allows you to attach your library. Fine let's go to Drupal now we're in the Drupal world and we're going to create a paragraph type called react target since that was the template file that we created we want to make sure that we're doing that so we create that. We really don't need any fields so then we go to the basic page and then we create a paragraph reference entity which I wish I had a better picture of that because I forgot to edit your content types going to basic page add a field of paragraph I can show you that in a little bit and then this just makes it their react target we hop into create a basic page we call it test stuff it adds a little react target on there we save that and well it didn't work I can't even do a live demo correctly if I prerecorded can I? Why? Why do we think that that's possible that this isn't working? No. This a lot of people don't know is the Oliverov theme not my custom theme because I didn't create that. So I go into my custom theme info.yaml I create a custom theme make sure the core version requirements on there I did a base class of classy and then I save it and once I save it I go in there and I see my custom theme available I install and set as default and still nothing that's because and I figured this out if I take a look at the console you'll see that it's saying it's a 404 to my app bundle thing why is that? go into my library and I actually in my folder structure did not use a react folder inside the JS folder so once I change that save clear cache ta-da my thing saying my custom thing is there and that's it for creating a block it's simple or excuse me creating as a paragraph so I thought what I do now is instead of killing I can't believe it took me less than 15 minutes awesome anyway so now we're going to do that actual demo and what I thought I'd do is we'd do it together we would actually take a block and create a custom module out of it so we go into our web folder and this is hard to see isn't it? is that better or worse? so here for we don't need to mess around with core just this is a quick this is my D9 thing that I do a lot of development I'm actually working on the smart trim module this weekend I've actually installed the admin toolbar, devil, paragraphs and token a couple of things but we want to create a custom thing the first thing I did actually because if we take a look at this slide classy is very very ugly and I don't mean that in a nice way either so I switch the base theme to olive arrow and then I go to this test site and now this is my test site and it has the my custom thing oh before I do that here's the actual working sites that I took screenshots of here's the TR electronics product search and you can actually see it actually loads things up really quickly really snappily faster than the Drupal search going back and forth does I still have no idea what any things are and then you link on to them and it says what they are oh no it actually just gives you an email I would like to know about this part number very interesting site this is the SFO flight status which is a react app as well you know I got to ask Ann because Ann actually worked on this what happened to the BART one we actually did one that interacts with the BART API as well so you can see when the next BART train is coming in there but I didn't see it so I couldn't take a screenshot of that and then here's Weather Underground which actually when I went to take a screenshot I lied that wasn't Drupal because they have I guess since 2015 replaced it from Drupal to just a straight angular app but it was progressively developed at one time but that's how they got get all the information as they actually slurped that in so anyway let's create a custom module first thing I like doing when I create a custom module is closing everything outside oh no I don't want to close that out good thank you because I created cheat sheets there so I'm going to go into this modules and I'm going to create a new file we'll go custom and we're going to call it app thing and then app thing.info.yml yay name thing what is the other core version requirement thank you auto complete we're going to make this for 9 and 10 and what's the other thing that's missing pull type and that would be a module and that's all you really need to make a module if we go in here and I'm using ddev and then I have some shortcuts for ddev drush so that makes everything easier I can go to extend and app things there there's no description there's nothing in there useful so that doesn't matter of course one thing that we're going to want to do is we're going to want to add a libraries so we're going to create a new file there library or libraries it's libraries one day we will learn how to type too and then we're going to call this the thing and then js and then we're going to finish that later because that doesn't need it alright so first thing we're also going to want to do is we're going to want to create let's create a custom block out of this so we create a new file and then we're going to call it it's going to go in the source folder scr src and then plugins thank you and then blocks and then appthing.php we're going to take the thing that I wrote up earlier because I didn't want to sit here and type everything out so appthings, plugin, block that's the namespace and then appthing block is actually what it's supposed to be called or I could either change that here to appthing or call it appthing block but I kind of like the idea of it having the word block in it and all this does is it creates a block base or it creates a class that extends block base we have to give it an id give it the id of appthing we give it an admin label and a category we can actually call this category anything that we want and all this does is it creates the markup of that same markup that we did with the other html.twig and with the attached library in there as well since this is a module appthing and then we're going to have the library appthing as well that's really all we need to do that we can actually run that if we appthing and see that's the app thing instead of the thing and again I could have changed this to the thing but appthing makes more sense it doesn't really make any sense but it also doesn't make a difference so we've got that going for us how's that? okay I'll always follow your phpcs everybody makes people happy and why is that still red? oh that's the library's holder is red because I don't have a finish on the js we can actually take that other library and we'll just kind of do the same thing with that but we call it a different library is that right? no that should be what am I missing here? I have a feeling that's wrong I'm just picking up so I'm just going to stick with it that we'll see what happens so this is really all we need to do to create this block so we can actually go here and we can go to block layout and let's go ahead and place this on all the content and appthing's not there anybody? keep calm clear cache hey no white screen to death I'm always happy when that happens content still no no because when you enable a module that flushes the castle automatically no oh thank you well no but the block so we should at that point we should still at this part be getting an empty block however it doesn't really matter because we need to actually create some stuff here so this is actually going to be easier if I go in here custom cd dot dot cd dot dot alright so then go into cd into modules custom appthing we're going to make a dir js oh mkjs and then cd into js thing cd app thing now we're going to run our friend mpm init this goes through the whole process of it that's really horrible to see doesn't make it any easier to see because the lighting in there but hopefully those of you following along at home haven't fallen asleep yet so we're going to call the package appthing we could call it something else version 1.0 description who cares entry point index js which is fine even though that's not really going to be the entry point there's no test command there's no get repository and is that okay and that's what that creates cool next thing we're going to do and I have a oops let that do it we did the mpm install before although for some reason this gave me an empty space here so that would have caused a big old error we're going to avoid that oh I should have shown you what was built out of that I guess I still can so we go into our custom module now we have oops custom module js appthing now we just have the package.json which is actually building as we go along I'm going to go ahead and kill this test script because it's not useful yet but we don't want to kill that alright that's all done and then I'm going to install react that's nice uncool and then as you can see this gets updated dependencies react react.dom everything's there now we're going to want to create the actual file itself so we're going to create src slash app.js uh huh and like I said before we're going to want to create the webpack so we're going to create a new file in here js oh what happened there I'm going to just copy and paste the other webpack it's easier source app js oh that's a couple of things to point out we want to make sure that's correct because that's where it's looking for and since if we would have called this in the source uh if we would have called this in the source something else we would have to update this and then we want to update the bundle name to that as well um the other thing that we want to do is in the scripts we want to change the scripts folder to match the other one which again is a nice copy and pasting that we can do which adds the build and then the watch which I'm not using the watch but that's always good to later so we have this security thing that asks us to update our apps in the middle of doing stuff all the freaking time it's awesome um anyway by the way that was sarcasm so now we have that oh the other thing that we want is the babble stuff I think I have I can find that easy yeah there you go and that is settled we don't need that extra what we do need oh that's good to to to everything's there cool we can go into uh js hopefully where am I we're right where we need to be so we can actually at this point npm run build we actually have a minimize file this is updated the disc folder right so app thing dist oh yeah that's right take a look at the library again app thing dist yes so that all should be working there now let's get to our original problem source plugin blocks did not work it's refresh any thoughts on why that might be people there's really no algorithm errors in our show I mean I feel like if you've done something terribly wrong with the block PHP how do you get white screen data yep oh well let's see file get contents custom oh that was from earlier today so that was not really that was when I was building the thing can't find the custom logo app thing is installed let's take a look at this again just to see the block correct returning the build yep all the build command is return to markup I'm going to look at this library again we are on the right side well yeah because that's the uh hold on are we on the server yeah test stuff is working all right we got my custom thing there that would have been hilarious because the actual here's the thing the folder itself is called Drupal 9 so thanks to the config.yaml which I guess I renamed to Drupal okay cool way to confuse yourself Mark this is right that's the logo that's fine block layout app things enabled source plugins blocks app things plugin blocks spelling matters kids should it be blocks or block should be block plugins in one place and plugins on the other look at the ah okay so let's actually do this maybe you have something that is code generator and all right and cache matter there anymore structure block layout still not there refresh the page sacrifice the chicken still not there right let's see refresh again keep calm refresh now I'm confused now I'm pissed because I'm not seeing anything that's wrong now app thing we could try that no shouldn't be source plugin block source plugin block you know what should we block in single mark there then block stealer and then plug in and block hey doesn't really let's go back to that there's the block we can configure the block and remove it and everything's fine so you know you saw that the hardest part of embedding a re-app component pretty much yeah creating a react app is pretty easy getting it in there and that's kind of what I wanted to show is how easy it is but yeah that's pretty much everything that I have for this because I didn't think I'd blow through the presentation as quickly as I did so are there any questions I guess so what's the role of the module well the role of the module was to create a block to create a block that has a react app just for an example yeah exactly so that was all it needed to do and it's like as I just said the easiest part about it is all it's really doing is creating this html that Drupal has to deal with and once you get that in there the react app takes over and just slurps it in now the problem is if I added a second block to this of course we would have a problem because then we would have two IDs of the same so if you're going to have multiple or actually if I were to go to let's see what happens if I go to that custom page that has the block and the module or the block and the paragraph it just does the one that takes the first one there so to solve that let's change this to let's see which one is this this is the block my plugin or my react block let's change that ID now of course we have to go into our javascript source did I clear that did I never create that let's see let's paste that and we're going to call this custom block and we actually want to change this to my react block because that's what the block is actually generating now right so both of those are saved we want to go here and we're going to go to npm build npm run build now we should be getting my custom thing but now we're not getting the content react target is not getting limited hey well that's actually curious that let's see we have my custom thing inspect my react target refresh oh there we go my custom block I never refresh the page alright so yeah we have my react block that has my custom block in there and now we have my thing which actually does the same things because it has separate IDs and that's the one thing that you want to be wary of if you have multiple blocks you can actually write your react to search for each of the you know do it instead of a query selector like this one does do a query selector all which gives you basically an array of items that you can load it into each one and that's going to be problematically in the future but anyway those are things that you can do any questions I like it as a block I think it's nice about that I think we did it with the bar block if I recall correctly we placed the block we made it a paragraph height that had a block field in the block field module and we replaced separate instances of the bar block like where everyone and the content of it through the paragraph right and then in that one we actually defined you can actually define the ID that you're looking for and it actually takes that and in the preprocess runs that argument through to the bar do I have that can I show it think anybody would remind if I showed it I'm talking about like anybody from from people who would yell at me I don't think so it's not a sensitive API it's open to the public it's a terrible idea I know it's the bar the next train but the way they do it it's so weird what was it instead of telling you the next train that's going to arrive at the airport they tell you the next train that's going to leave and Barcadero headed for the airport it's just useless you're just going for the train but that's what we have to work with so I have a feeling it's probably going to take it down it wasn't what we did it's just that the data is nonsensical why is my it's not letting me switch projects saying one unsaved that's this one that's unsaved I would like to close you yeah I was trying to figure out a patch yesterday something was going weird with the visuals VS Code was adding an extra line to the patch and then the patch was failing because of the extra line it's very very annoying which I still don't understand why that is but still he said just do it in Vim and I'm like yeah then I'm never going to be able to exit and alright let's see switch open with fly us over no don't save so apparently that pop up somewhere so let's see yeah this is the BART one that's that here's the block for the BART PHP we're doing a little bit more with the forms we actually do a custom create we get the config with the form we decide what direction they're going northbound southbound and then the default is southbound so southbound trains are the one going to the airport even if you're coming from the southern area and then northbound trains are going from the airport it's also an application because at some point there will be a bar in the north city correct correct this is the submit obviously it saves the configuration for the thing and then in the build here this is actually where we do that we create a class of BART schedule block and then we create a data of the direction from the config we add our library and then we get the BART key which is stuck in the settings yeah that was the weird thing too that so if we take a look at our BART React source BART JS we actually needed to deal with dates so we included date functions we imported some fancy styles which I think there were two lines in that style sheet the BART API is set in Drupal settings which is fine which is what we set in there we actually did some logic as to go the different way here's the actual API URL and then once we did once we started it we did a function called getit which actually goes and gets the stuff and then oh is that the interval how does it know when I never understood that so this has it refresh every hour yes 500 mls anyway so then we actually do some custom logic in here which station we're going to and then we go through each of the items or because each call would come the next three trains we could actually say the next train is 5 minutes away the one after that is 15 minutes away the one after that is 20 minutes away and then we had multiple directions if there's an error we just gave them a nice link saying sorry check the schedule yourself that was the other funny thing is this API goes offline like every day like 8pm for a couple of hours and then so this is where I was talking about instead of doing a element by ID we do get elements by ID or you could actually do a query selector all which is the same thing and then for each one of them we go ahead and render in the direction and this way we actually had north-south in the same page without a conflict of what's going on and I don't have that spun up actually I think I destroyed the environment so I can't even pull it up so I can't show you but that's what one is the TR electronic ones I deleted that one I can actually get that TR electronic D8 I don't know if any of you have seen this function this is my favorite part of github right now you press the period and it opens the whole repo in visual studio code in your browser and that just makes finding files and everything so much easier so you go to the repo and then you hit the period and yeah what was that in the browser I don't know if it's just chrome I'm actually on contract with another company and they have their own self-served github and it doesn't have it installed and I am yelling at them night and day to get that back installed but they don't seem to want to listen to me what the heck try again well I said it was great but then it didn't work look at that so we'll do it the old-fashioned way what we can do is opto-tree because sprint was either deleted or you don't have access to it oh weird where did I put that put that themes somebody else generated the theme they called a Keaton and for all their placeholder images are Michael Keaton's Batman so very interesting people whoever so here's the product list does it work this time the source on this one basically I get to react I have a TID which is the product list term ID that's pulling in actually I guess I show to get that is it over nope that one's definitely not there includes paragraph process paragraph a little bit bigger alright so in the products paragraph we get the route to see what term we're on so you can just place this paragraph and then it grabs the term and then it actually does some searching for the actual information what's that term term get names and then it just creates this content of all the content that's in there and then what happens as well as you're searching in the index.js it actually updates what you're trying to look for and there's an endpoint product search that I created I believe in a custom module that returns the information in terms of class list and it's fully fully sussed out in their act and then that's only done one place you can only place that one in there because it's getting a query selector of an ID and there should only be one ID in your world any other questions, comments dance moves not one dance move for those playing along at home so so are you committing all the derivatives to the code by CI or what do you recommend with our CI I would recommend building it and then committing it I mean hopefully usually you want CI to build everything but if things are in different places the thing about the circle CI or any CI is it expects it to be themes custom there you are done but if you have one thing over here if you have a couple modules that need to react building then you should probably do that that's also a good place where a library having it as a separate library the actual react as a separate library that you pull in by a composer and put it into the Drupal libraries and then reference it there in your custom module then the CI for that repo builds the output for you as opposed to the other way around so it's really big or it might have a repo or if I'm using a reusable library like if we wanted to use Bart on another you know another Bay Area thing then we would just put that in another repo build it have it built out and then make sure that we point to the right libraries yeah we're really leading towards a thin repo which means that our repos are going to be just composer files our custom themes are actually separate repos that are built separately as well and then we pull this in by a composer as well I'm still not happy about that but I'm working to make myself happy about that it's kind of been told on high to do and then now I got to do it but I guess that's why we all have jobs right alrighty well thank you all for coming and we'll talk later I want to finish with my last slide thank you