 Thanks. So, yeah, I'm Phillip Johnson. I work for Bolster, presented last year and we talked about the setups that we use for our festival sites. So, Bolster primarily does music, entertainment, festivals, tours, all those sorts of things. So, this year I'm talking about WordPress, Gatsby.js and Splendor in the Grants. Now, one of the conversations last year was from Leon Stafford and he presented about static websites and we're using WordPress for that. Really interesting discussion. At the end of my talk, someone said, hey, have you ever thought about using a static site generator for these festival sites? I said, no, no, no, it doesn't really work with our clientele because they like to be able to have updates too quickly and it's just, it doesn't really work. Since then, we've used Gatsby.js which is a static site generator. But I'm going to tell you all about what we did with it. So back in 2018, towards the end of the year, Secret Sounds came to us and said, hey, do you guys want to go through and build the new Splendor in the Grants website? And my boss came to me and said, what do you think? I'm like, yeah, I really want to do this. This is going to be awesome. He said, have you thought about this? I said, yeah, yeah, it will be fine. He's like, you've come to me and said that you're looking to move back to Brisbane. This project will be taking place during that time period so you're going to have to move across two states and lead this project. Fortunately, my wife was very understanding and after a lot of late nights, you know, we finally got this project done. So we built Splendor in the Grants. Now, it was a challenging site to build. We'd been talking about using React with WordPress. We'd been talking about using headless WordPress for some time and we were just trying to find the right project to use it on and we thought, this could be a great time to do this. So I sat down, we've got a head of product and we kind of had a conversation about what we'd use and we ended up with Gatsby JS, primarily because of that static site generator. Because Splendor in the Grants is quite, you know, popular, I don't know if everyone knows what it is. It's a rather large festival that happens in Byron. So we were like, look, let's go through and use the static site generator because everything will be then stored in S3 buckets. We don't need to go through and worry about server load. So like, okay, there's a lot of unknowns in this. This is going to be really quite difficult. So fortunately, I was able to steal a couple of developers from his team to help me out on the front-end development because I don't know much about React. I certainly didn't know anything about Gatsby. So I worked on API development. They worked on the front-end development and we got there in the end. So this talk, I'm going to primarily focus on some simplified things that I wish we knew when we started. So I'll cover the API development and how we created headless WordPress. I'll talk a little bit about the Gatsby JS setup. There's so much stuff that I would love to discuss, but I don't have the time. And I'll also talk about how our client reacted to it and some of the things that they founded a little bit difficult and some of the things that they really enjoyed with the setup. So API development. So does everyone know kind of what headless WordPress is? Like, hands up if you don't know. Cool. All right. Hands up if you know what Gatsby JS is. Has anyone used Gatsby? One or two. Cool. All right. So headless WordPress is essentially using WordPress' API only. So there's no front-end theme. It's all you're really doing is you've got a theme installed and you're pretty much just outputting data that people can use. So you've got a rest endpoint that people can access whatever you want. We used ACS. So Elliot's here. Thanks, man. It was a really good thing to be able to use. We had looked at using Gutenberg. Now, Gutenberg is great if you've got that front-end theme and you're going through and you want to be able to see things as they are. With headless WordPress, the idea would be more so that you just want to be able to get the data. The other challenge is like Gutenberg is designed so that you've got your styles and also stuff built in within your theme on WordPress. But because we had a completely separate React app, there was no styling coming through in WordPress. So it didn't make sense to use Gutenberg. So we used ACF and primarily the flexible content fields. Now, one of the talks yesterday from Alex really covered this in a lot more detail. I recommend going and checking some of that stuff out because he covers a little bit about why you would use flexible content fields. For us, we use them pretty heavily. We also created global content blocks. So you can kind of see here that we've got a list of every single block type that we're going to be using. You could add it to the page. You could enter your content in. And then we had these global content blocks. So we used flexible content fields along with the clone feature inside that, which meant that we could create these page templates which adopted the standard layouts that we wanted. It was like, cool, these are all the fields you want. So we created fields specifically for those content blocks and then we cloned them back into our flexible content that we then used within pages, posts, artists, whatever it is that we wanted. We just used the ones that we needed. So by doing it like this, we were able to give the flexibility to our client. They could insert the data as they needed. They could just do all that sort of stuff and still have a rest endpoint so that the front end could pull the data. They could format it how they needed. It wasn't tied to the back end. So if we needed to change the styles, it was all done by a different team. So that's why we used ACF over something like Gutenberg. The next challenge was the API was to be consumed by three different areas. The front end obviously was the Gatsby JS. And then we were also needed to work with the mobile app developers because it was, well, the client in the past had been entering content in for the app. They'd be entering content in for the website and that it's just mishandles, particularly in the first full space where things do change quite regularly. This year, Chess Rapper pulled out. So they had to update the content once and it updated in the app and it updated on our site and they didn't have to do that double handling. And finally, it also was consumed by the AR team. So they had an AR component inside the mobile app, which then you could use it to look around and it told you, hey, over here at this tent, this is who's coming up next. This is who's on now. So they were consuming our API as well. And that presented a couple of issues because WordPress's REST API is good if you know WordPress. There's a lot of terminology that's in there. You've got these cross-reference fields and lots of stuff that basically for WordPress. So the mobile app had their own API at one stage and it was like, cool, this is how we set up our field. So I had a good conversation with them. So we decided that we would not use the default WordPress API and we rolled out our own using Laravel's eloquent. I don't know if anyone's used this, but it's actually really good for API development. It made things quite simple and easy. And I'm going to breeze through some of this because I think more people are going to want to know about Gatsby. But this is the area that I primarily worked on. So I'm pretty passionate about it. One of the things that we did was we registered endpoints for every single post type that we created. So we had a base post type that had a register function in it so that any time you registered a new post type, it just ran through this. And that callback method was all we really needed to do to have everything at that end point. So it didn't matter whether or not it was searching every single artist, it would just handle it and I didn't need to change that function over and over again. And that made things very easy. So just to quickly touch on how to array works. Inside your model, you've got a to array function and this is all covered in eloquence documentation, really well documented. So I just went through and said cool, for a standard post, it just needs WordPress ID, all that kind of information and it would just kind of spit it out. And then if I needed to extend it, I would just basically run this inside a different model and then output it, put more information in it, remove it as needed. One of the really good things I like about Laravel's eloquent is the collect function. If you haven't used collect, it's awesome, it's really great. I didn't want to be seen, it's okay. Yeah, the collect function is really good. Basically it takes an array or an object, it turns into something that can be queried, collapsed and converted to an array and you don't really need to do much. So check it out if you're doing a lot of PHP, you can install a composer package and just use collect by itself with any project that you've got. Just touching on the content blocks. So all the flexible content fields, I ran through a little function called get blocks. And this is essentially all it was. I got all the fields, I plucked out the name, I had a class specifically for ACF groups and that handled all that, you know, the formatting of the data. By default, if you created a new flexible content field that wasn't set up, it would just give you a raw dump of the data or it would give you a formatted, you know, nice and named area if you added that extra class. So I was pretty happy with that. A couple of the other things that we had to do differently were permalinks. So once again, separate headless WordPress, separate front end URLs are completely different. So I had to rework some of that sort of stuff. So I had to change the home URL. So it was instead of like the API endpoint, it was using the front end URLs. The other thing was that for some of these post types, like for example, FAQs, the URL structure was different. So I know you can change it in like your permalink structure, but it's not necessarily specific to that post type. So I use this little filter. And I would add that to my model for FAQs, I had to do it for artists because, you know, artists will have a parent of the lineup page and they were all on that one area. So I did a couple of little things. But permalinks is something that you're going to want to take a look at if you're going to use a headless WordPress theme, you're going to want to rethink how you do your slugs, you're going to want to rethink how you do your permalinks, you're going to want to rethink how you show that sort of stuff. So by using this function, it just spat out that in the permalink. Then when it was, you know, we had Algolia search on there, so it pushed to that. And then you didn't have to try and find a fancy way of doing it. So those are some of the very basic things that I did in the API. There's a couple of things I refer back to as I move on, just because there's a few little gotchas that you don't think about until after you start using Gatsby. So Gatsby has got this plugin. It's essentially if you don't know React, you're going to have a very hard time with Gatsby. It is a React-based application, so you need to know that off the top. So I'm not going to dive into too much of that. It's also based on GraphQL, which is one of the biggest gotchas on this with WordPress. So if you haven't used GraphQL, it's kind of a different way of querying your data. So you've got your rest endpoints, which is like, cool, I want to know this one thing, and it returns it. GraphQL goes, I want to know all these 10 things, and it just returns it. Now, with Gatsby source WordPress, it converts your rest endpoints into that GraphQL, so you don't have to do it. Now, at the time, we got a lot of these kind of responses on the Gatsby documentation. So we struggled, because that's not helpful. And I really liked the, was this doc helpful to you in the bottom right corner? No, it wasn't. They have updated a lot of stuff. So there's a few things that I was going to talk about, but they've updated in their documentation now, so I'm going to skip over some of it. So back to that GraphQL setup. It uses what they refer to as an inferred schema with WordPress. So it takes everything that's at those rest endpoints, and it goes, cool. So I'm assuming that this is the type of content that you always have. So it scans through your WP JSON endpoint. This looks easy for you if anyone's looked at that. It will find every single endpoint that you've got, and it will go through and convert those. Now, it's in your node setup. It does have these included and excluded routes. I couldn't figure out how to get the excluded routes working. I had a huge time, like spent on it, couldn't figure it out, which is a slight problem, because if you're querying every single endpoint that you've got on a website, if you've installed plugins like, for example, Yoast or WordFence, they've all got their own REST API. You don't want that for your front end, but it's going to query them anyway. And if you're building an app on the fly, it's pulling a lot of data that's not necessary, so I really want to try and find a better way of doing that with the excluded routes. So, inferred schema. Really good up until we started seeing this error during the build process. We're like, okay, what's up with that? You don't see these things necessarily when you're developing it because you fill in all your data. You sit there and you go, cool, I know I'm going to need a menu structure that's got a child. It's like, hey, I've got a submenu on the site, that's what's in the design, that's what I'm going to develop with, that's how we're going to do the front end. We kept on seeing this with a whole bunch of different pieces of our data because we were using this inferred schema. And this was a problem. So, I jumped into the fragments, so if you, once again, GraphQL, React, you're going to know fragments, you're going to have to learn it. It'll take some time. So, this was the fragment. So, the fragment was essentially cool. We're expecting this information to come through. This is all that we want. So, we just wanted for the menus, a title and a URL. That was it. And it has WordPress children. It's like, cool, you'll also have a WordPress child, which is all your submenus. This is all we really want. And it was erring out. So, I jumped into the rest endpoint and took a look at what was being returned. So, when we put it onto a QA site, none of the data had been filled in. No one had actually entered in this child menu item. So, this is kind of what they were getting back. And this is what we were expecting to get back. So, the main difference is that WordPress children. And this happens over and over and over again with the setup, because you can't always return everything in every possible option. This is the biggest gotcha that we had. This was the most painful thing that we went through. Because when we started, there was no real good option. So, in the past, we had solved this problem by creating dummy content that we just ignored when building out the site. So, we would go in and fill in every single piece of item. But I was very worried about giving that to a client. Because if they deleted the post that had all of that stuff in there, then it was going to throw those errors again over and over and over again. And so, I spent some time with the front-end developers and they're like, look, you've got to do something on your end to fix this. I'm like, but it's really complicated. Like, you can't define a schema that gets returned. That's not how it works. And so, yeah, it was like this. Honestly, this was like almost a breaking point for some of us. Unfortunately, one of the guys spent all night. He was contracted in. I've worked with him quite a lot. And he spent all night looking through the documentation. He was like, look, I found a solution. This was almost his responsibility. He's like, I found a solution. The newest version of Gatsby allows you to find your graph QL. Now, this is the most important thing if you're going to use Gatsby and WordPress. Define your own schemas. It will save you so much pain in the long run. And this, honestly, spend time and do it. It's time consuming to do this sort of stuff. But this is how we went through and ended up defining it. So, they've got some documentation around how to do this now. And so, this just goes into your Gatsby node set up. And it's like, cool. When you hit the WordPress API, menus, menus, items, look at this. This is what we expect. So, if it doesn't return that in the rest API, it's okay because you've already said, hey, we're expecting a string. We're expecting items to be a menu item. And this is what menu items look like. And that's where we put WordPress children. As soon as we put that in there, everything was great. It was solved. We had no more issues with that. Obviously, this was just for menu items. You also then need to go to do it with every single post type you've got, every single type of content block, all those sorts of things. So, this is a quick example of how we handle pages. A really cool feature that I found after we finished up with Splenda was this featured post at the bottom. Now, what that is, is you take a look at content blocks above it and you see, basically, that's saying this is an array of this type being returned. Underneath it is, this is an array of IDs which should be linked back to your posts endpoint. And this saves a whole lot of problems that you'll run into. There's a gotcha in this as well because it also creates some problems. But by doing this, you could go through and have featured posts or artists return an array of IDs and then Gatsby and GraphQL will just go cool. Let's look up that other endpoint, match it by the WordPress ID which is defined at the top, and it just goes cool. Let's link that in. So, in your fragment, you can just reference how you would an artist or a featured post and it's done. So, this is super helpful. It also makes your headless API much faster to query. Really good. Next challenge, we had a hybrid app. So, everything gets compiled down to static sites. And then we had this option to be able to sign up to My Splenda. And that was just essentially, at this stage, all it is is that you can go and favorite artists and it'll go through on your timetable page and give you, hey, this is when they're playing, this is your timetable, this is what you should go and check out, these are all your clashes. So, when you're doing a static app, you don't have the ability just to get dynamic data. You can't find out what a user's doing. Gatsby's got a really good set up for client pages and that's kind of designed for, you log in and then these are protected pages, which is good, but it's not necessarily what we needed. And I was like, hey, why don't just when we have that component on the page, we just run a request to the database, like, you know, hit the endpoint. So that's what we did. So we used Axios. Nice simple, you know, Ajax library that just hits an endpoint, returns it. So we basically used that and that solved that problem. Really nice sort of simple solution. We had a login service, so when you logged in with Facebook or Instagram, we had it hit that API. It gives you a token back and then you post it back to your login service on WordPress and then we got a JWT token back. And then any other request we've made to WordPress because we were using WordPress users, it just returns, you know, the favorite artists that you've got. And then when your favorite an artist does it all over again, just goes, cool, got the JWT token, we stored that in session, pushes back, yeah, let's hire it out. That was just a nice little thing. This is another problem. This is not Gatsby, this is React. So if you're doing a lot of client work, you might have clients that want to put ads on their website, or they might want to put Google Form in beds, or one of our clients is like, hey, we've partnered up with booking.com, they've got a little booking widget. Can you just drop this onto the site? Typically with WordPress? Piece of cake. With React? No, not at all. So I didn't put that thing, I've got that later. Yeah, it just doesn't work. There's lots of little gotchas you've got in that. There's no real good solution. I'd recommend just looking out, figuring it out. So load testing, biggest benefit of something like Gatsby.js is that it handles load well. Now, this was our basic infrastructure. We had everything, WordPress application side, was in that blue box. We had deployments running through CircleCI. It uploads everything to an S3 bucket and we had Cloudfront over the top. So our load testing fleet would just hit the Cloudfront. So I was reasonably okay with it. Obviously, our boss not quite as familiar with how this stuff works was very worried. So we had, our DevOps guy had planned, cool, let's run Lambda artillery and just test it, had 9 million lambdas. When you're, when you're typing in 9 million, it's sometimes easy to add an extra zero. So he, fortunately, he noticed halfway through, but it's about halfway. So we went through and ran 90 million requests, zero failures. Obviously no problems whatsoever, not an issue. So on launch day, I wasn't actually looking at how many of these we had on the site. I was doing a lot of stuff. So at client side, they were really thrilled that, you know, we had set this up. One of them, they were obviously concerned about hackers. Sweat on the grass, obviously very popular. People do try and get the lineup. So we had, we had the API server all protected. It also meant that our front end, because it was static, there's nothing to hack. You can't hack a static site, there's nothing that you can get out of it. So we were fairly confident. So that was one of the huge benefits that we had on that. The server load was obviously a good thing as well. One of the gotchas, preview. So going back to when I was talking about the way that you could return artists and featured posts in an array. Originally we were just returning an extract of those posts. So it just had, you know, title, image, excerpt, and a link, which meant that when we hit the preview pages, we created these previews pages once again with Axios hits at an endpoint, it returns all the data you need just for that one post. Previews worked well. Switched it over to use those array of IDs. No, you can't do that, because those IDs are being referenced through GraphQL, those being matched up through GraphQL. So when you're using that, it doesn't have anything to match it with. So rest of the GraphQL, don't play nicely together. You can't do those cross references. The only way we would be able to get around that would be to then say these are all the IDs, run post requests to the rest API to get that data back, fill it in, see if there's any other, just keep on going. It wasn't good, so it doesn't work. At this stage, I really wish we had gone down the route of using something like WP GraphQL, because then it would have a GraphQL on the server. It would then mean that instead of using Axios, we would use something like Apollo to query that GraphQL database, the GraphQL endpoints, and what you would see on that API would be the same way that you would handle your GraphQL in Gatsby. We had talked about doing this at the beginning, but I was already worried about the level of unknowns that we had, and we built this stuff in about a three-month period from design, API development. We had never done something like this, and we did it in three months, and I moved in the middle. I don't recommend it. The next thing that they struggled with was the deploy. So deploy, we had a nice little button that just said deploy, hits our circle CI, and it goes through and runs that build script. Now the reason why I said last year that we don't do static websites is because clients like to be able to have a quick update. The deploy time for this purely because of the way that you have to convert the rest endpoints to GraphQL takes over 10 minutes. Now that's incredibly stressful for a client when they need an update. Chance the wrapper, they didn't go through and have some socials for him, and he was not really happy about that, or they were like, oh, we've got now an approved image for this artist, because that stuff comes through the night before, the day of, and so they're constantly doing updates, and they click deploy, they have to wait 10 minutes. So that was the biggest downside for them as well. So they couldn't preview the data. If you were trying to build it, it would then take 10, 15 minutes. So that was the kind of two downsides that we're still trying to find a way around, and I think a lot of that would come if we converted from REST API to using GraphQL. So those are the most of the little gotchas. There's a lot of other stuff that I would want to flag, but there's no time, and the documentation is much better now. So you can jump in and go back and find all those little issues. We had problems with images. Quick one, static site when they get built with React, you don't have a window. So if you're using window and you want to get the size of the window, if you put that in your application the build will fail, because it doesn't know what window is, because there is no browser. Handy little tip, make sure that when you're building it, because also when you use local environment, you're probably not building it, you're actually just running it in the browser. So you'll actually run it in the local host and it just browsing. So what do we learn? Take your time. Building this stuff in three months is intense. Plant it out. Think about how your client is going to use it. This stuff is really good for simple sites. If you're going to do something complex, it's going to take longer to build. Define a schema. Honestly, it doesn't matter what you do, define a schema, make sure that you've got that in, because that's going to save you headaches, it's going to save you build times. And set that expectation with the client. Say, hey, look, these are the benefits, these are the cons. Have a conversation with them and find out if that's a solution for them. For us, because we had that ability of zero chance of it crashing, we had that security element to it, so we didn't have to worry about people hacking into the site, because we had our servers protected, we could IP lock it down, we could do any of this stuff. But you guys had their expectation of it's going to take ten minutes, or if you've got a small site, it could take five minutes to update content, and if that's important to them, then you might need to find another solution. So those are a lot of the learnings that we took away from this. Yeah, look, any questions? I'm happy to try and answer them. As I said, I didn't work too much on the front end. I did recently deploy this site using for falls, and I had a lot more experience on the front end. I learned all these little gotchas. Any questions? Yeah, got one here. Check one, too. So you said the favourite artists and then getting the favourite artists back was an API call to WordPress. So I'm quite curious about how that scaled and how you handled that, because that sounds like it could have been quite intense in the lead up. To be honest, because we didn't roll that feature out until later, and it was kind of more of a soft launch, because we hadn't done it, we weren't too worried. So we didn't get a huge number of signups because of the way that we kind of just wanted to test the waters with this. We would go through and put WordPress on a load balancer and that would solve that problem, because it wouldn't matter then and you could auto scale it. So if we started getting lots of those requests, it's a load balancer. You've got an RDS instance like, yeah. So that's how we would handle that and handle it at scale. So I mean, my only concern was if they were to hit it while that build was happening. That would be where I'd be most concerned, because that is going to be using a lot. But once again, put it behind a load balancer and you'll be fine. Cool, thanks. Oh, I'm getting my exercise now. Run, Ricky, run. Good day, my name's Pat. Thanks for that. My question is ballpark figure for building a site like this. Ballpark. Look, I mean, we did it a loss because we did plan on reusing a lot of this sort of stuff. So we built it with the intention that we would work further on it. Honestly, it comes down to the skill set. There's a lot of learning involved. There's a lot of stuff. So to be honest, I wouldn't consider doing this unless you've got a React team, people that understand WordPress API and a lot of time. So it depends on what you're charged. But to be honest, I wouldn't want to quote this out starting from scratch again at less than about 100K. It's expensive. It is time-consuming but you do get a lot of good benefits out of it. And once you've got through that learning process then it does make it quicker. We spent three months building this site and we spent a lot of sleepless nights when it came time for me to do it again on falls. We did it in less than a month. We even skin the front end of it in, you know, two weeks. So it made it much faster. So then did you start with wireframing then high-res designs before you got to the point of the build? Yeah, so I mean, fortunately because we do a lot of these sort of vessel sites I already knew what type of content we were expecting. So the designers were going off and doing wireframes while I was able to start work on the API because I knew hey, this is the sort of content we're expecting. And we had a lot of conversation. So while they were still doing designs and wireframing and style application, I could get started on the API. And while I was starting on the API I could then also get our front-end team to start thinking about how they would set it up as well. So we had three teams working in tandem. There's a few little challenges. So, for example, the front-end developers ended up using something like Storybook to build out the components which if you're going to use Gatsby definitely go down the route of Storybook because you can just build out those components, see them and then once your API is ready start fitting in the stuff. The other thing is when you're doing it locally build time also is about 10 minutes. So when you go yarn start you're going to sit there and wait for it to pull the data and then you can start working on it. And if you get that schema wrong you're going to be doing that every single time you get errors because you cannot start working on the data until after it's been built. And if you change the data you have to rebuild. So that's one of the other big gotchas that we had and it's like cool plan it, get it down first and then you'll be able to go for no problems. Anything else? That looks like it then. Cool. Big round of applause for Philip. Philip's going to be here with us so if you have questions go out we have another presentation by Joe.