In this workshop, we will go over how to build a knowledge base using Gatsby, a static site generator Framework that uses React and graphQL, Contentful, a Headless CMS to drive the content and deploy it to AWS S3.
Build a knowledge base with Gatsby, Contentful and AWS
AI Generated Video Summary
This Workshop focuses on building a knowledge base using Gatsby, Contentful, and AWS. It covers the basics of Gatsby, including static site generation and routing. The Workshop also introduces Gatsby Content Mesh, which provides a GraphQL layer for adding various data sources. It then demonstrates how to integrate Contentful, a Headless CMS, with Gatsby using the Gatsby-Source-Contentful plugin. The Workshop concludes with deploying the app to AWS Amplify and setting up webhooks for automatic redeployment.
1. Introduction to Workshop
Hello to building a knowledge base using Gatsby, Contentful, and AWS Workshop. My name is Abderrahman Aedel. I'm a solution architect at Rangle. Today we are going to build a knowledge base using Gatsby, Contentful, and AWS.
So, at Rangle we make things that matter. We believe in doing the right thing, the right way, and then improving it. We have been in Toronto and Amsterdam. For more than nine years, we founded in 2013, and we have over 150 team members. We serve a lot of clients who are building their own product creation capabilities through immersion and the enablement systems.
Today we are going to build a knowledge base using Gatsby, Contentful, and AWS. So, this is a table of contents of what we are going to do. So, since most of what we are going to do is like live coding, so I'm gonna try to go over these super fast at first, and then we can just jump into the code.
2. Introduction to Knowledge Base and Gatsby
A knowledge base is a self-service online library where you put all the data and your knowledge dump, everything you have, either to help team members or customers. Today, we are going to build a homepage, a categories page, and a page for every category and for every category we'll have a bunch of articles. Websites can be rendered through server-side rendering or client-side rendering. A new concept called static site generators came out, which take all the queries and fetch them ahead of time, generating actual HTML pages and building them on the server. Gatsby is a modern site generator that supports most modern requirements and is built over React. We will show you how easy it is to build something with Gatsby and how fast it is to migrate from something static to something dynamic using Contentful.
So first let's know what's the knowledge base and why are we picking a knowledge base instead of a normal blog or a news website or something like this. So, a knowledge base is a self-service online library. It's a place where you put all the data and your knowledge dump, everything you have, either to help team members or customers.
So for example, if you are a company and you want to have some place where the new employee will jump in when they join and understand how the onboarding works, how the communication works or something like this, you can have a knowledge base in place. If you are a company that's providing service for customers and you want to document everything you want in some place, instead of having everyone having a question asking the customer service, you can just create a knowledge base or like a help center or a place where you double click on a page and you can put all the FAQs and articles and you can put them into categories and stuff like this or troubleshooting guides. And yeah, the customer or the team members would just join, jump in, find the right answer to the question instead of bothering you with multiple questions.
Today, we are going to build a homepage, a categories page, and a page for every category and for every category we'll have a bunch of articles that will have also a page of rich.
So first, let's talk about how websites are rendered, because the concept of static site generators are very new, or not new, but like a lot of people don't know how static site generators work. So let's go from the start. How do websites get rendered? At first, when the internet came out, there was only one way to render websites, so it was called server-side rendering. Well, there was no name because it was just the only way to do it, where you have a server and the client and the client or the user type the URL into the browser and then send an HTTP request to a server, which does the magic, generates a whole HTML page with everything you would need, and then get, like, pass it back to the browser where the browser would paste the HTML and render it in the browser.
And then every time you want to switch to another page, like you want to route, if you are in a home and you want to go to help or something, you would click on an a-link, on a-tag, that would send another HTTP request, get the whole HTML from the server and then replace everything with this new HTTP. The server uses templates to dynamically generate full HTML pages. So you have, for example, a PHP website where you send, if you send like a GET request to this page, it will be handled and then it will put all the variables or the actual data into an HTML template and then send it back to the browser.
So the crawler would go into a link and get an empty HTML page and find no meaningful content in it and then this way you get an empty page that doesn't get archived or it would be very bad for SEO ranking for it. After a while a lot of crawlers or a lot of search engines adapted but it wasn't this fast and it wasn't like working 100 until recently I guess. the build time was super fast and caching was happening only on the client side because yeah like you don't you get only you get you get every time you get the same page so there's no caching that can happen but the client was caching the API requests on the client it depends on how you configure it of course but like normally it would cache it but it wouldn't thing and to fix this issue with the SEO mainly a new concept came out which is a mix from the first thing which is server-side rendering and the second thing clients client-side rendering so for single page applications every time you send the first API call sorry the first HTTP request instead of having a very empty HTML page sent to you you would have like that server would do the first render like it's happening on the client and then send you the full HTML page where the client would render it and then happen something called rehydrate where you will you will rehydrate the state and work as a normal single-page application.
So what's a content-driven website? A content driven website is any website that is mostly like the most main object of it is to deliver content instead of like having a lot of tasks tasks in it. So not a dashboard or like not a social media app, not a web app, but some website that it's like it has a lot of content that's mainly like text rich text assets like images and stuff like this, like a blog and news website, a company website, marketing websites, or a knowledge base. And when the content-driven websites had the static site generators, came out.
So what's a static site generator? So we still have a client and a server. But there is something happening on the server, even before you ask for the call. You asked for the HTTP request. So what happened is that you do everything as a normal single-page application, but instead of fetching the data and rendering on the runtime, you do it on the build time. So the server-side generator, the static site generator, would take all the queries that you have and fetch them ahead of time, and generate actual HTML pages and build them on the server. So that every time you want to have an API call, sorry, an HTTP request, you would send the HTTP request to the server and server would give you that prerendered HTML page ready for you to go. And then the whole operation continues like normally, the server-side rendering. So the app would still get rehydrated and the single page application takes over. It doesn't only generate these, but it also takes care of routing, so you would be generating a bunch of JSON files that have the data for other pages. So instead of sending multiple API calls to get also the content for the other pages, you would just fetch this JSON, put it on the template, and here you go. You have the other page ready, even after the single page application starts working.
So for aspects here, render time is faster, because there is more render. Like most of the job is already done in the build time. ICO is super good because crawlers can now... Can now fetch the data faster than ever. The build time is lower, of course, because you are doing a lot of stuff and you also take more space. But if you're talking about a bunch of HTML pages, it doesn't really look like a space. And caching, of course, is supported, because the HTML pages are there, and also most of the frameworks support caching out of the box.
So, to summarize this, the client side rendering, the render time is inconsistent, ICO is bad, build time is fast, and caching will happen only on the client side, the server side rendering, render time is slow, ICO is good, build time is fast and caching you can do through a third party, like partially supported. Static site generator would have faster render time, a good ICO, a slow build time, and supported caching out of the box.
But the limitation here for static site generator would be you have to have a static site to use a static site generator, you know? It's literally in the name. So you cannot do this for a dashboard, you cannot do this for an app that has a lot of stuff that are very different like, for example, a username or a user data. You can't use this for like a profile page for all the users because you cannot generate pages for sensitive information, you know? But you can do it for a news, for a news website, for a blog website, or, yeah, in our case here, knowledge base.
And that takes us to Gatsby. Gatsby calls itself a modern site generator, not just a static site generator because they have adapted to most of the modern requirements and they can offer you everything, mostly everything you need when related to normal websites. And the very nice thing about it is that it supports most of, well, like, yeah, almost everything out of the box. It's built over React. So if you have a knowledge with React, like even familiar with React, then learning curve is very shallow for you and you can easily, like, yeah, in a couple of days you can get something working with Gatsby. It's very easy. It didn't take me a lot of time to to work with it. So it should be super easy.
And let me make something here super clear that what I'm trying to to accomplish today is that not just not show of that Gatsby or like this kind of scales, but I want to show you how easy it is to build something. And later, when we we use Contentful, I want to also show how easy and fast it is to migrate from something that's very static to something that's super dynamic. And also with the deployment, it should be easy and straightforward for you.
So that takes us to the end of the theoretical part. And now we should jump into the code. So before, before we get into this, so we have a Q&A panel that you can find in Zoom where you can ask questions that only the panelists would find and then we can answer them later, or you can just drop your question in the chat. We also have with us Matt Van Voorst, we are very happy to have him here, he's a software engineer from Contentful and he will be happy to share with us or answer any questions related to Contentful. So, yeah, that's it, let's jump right in.
3. Setting Up the Workspace and Exploring Directories
4. Exploring Files and Creating Components
In this section, we learn about formatting files, the Gatsby config file, the package.json file, dependencies, the public directory, the static directory, the page data, and the div 404 page. We also create a new file called categories.js and a 404.js file. We create a header component and add routing functionality to the categories page. Finally, we create a fragment in the index page that includes the header component.
I think common shift F, sorry. Yeah, it's option shift. I'll shift F would format the whole thing. So if I do it like this for example and shift F yeah, would you move it in and pretty much format it and also you can see another file here called pretty ignore where you ignore this file. You don't want to change or reformat this files.
You have the most important file here called Gatsby config, which we won't use right now, but we will use later. You have the package of Json with a bunch of scripts you see the most important here are the developed which is basically the start and the build. And there's also a format here. You can just run in VM run format or a yarn format, and it would tell printer to format all of these files with these extensions. A bunch of dependencies here is the gatsby-react and react-dom and the printer has the dev dependency. And there is this public directory that we have here. And the reason why it's super full you shouldn't see it's this super full at first because this happened because this tool get bot run mvm run build at first. That's why so we have the actual app here. And if you look closely to the index HTML you see that our page is actually generating, statically generated and has a hello world. Why it's not, it's it only has the hello world because it doesn't have, it didn't reflect our changes or the developer. It was just run once when first it was running mvm run build and then you can see the static directory which will contain everything inside this directory. No, sorry, you know, static directory files would be moved here as you see, like the Fabricant here if you post an image here, it would be also moved here. The static is for yeah, as for optimizing files. We'll talk about this later and page data is the, an index here and has a JSON file. If you produce this... So I'm trying to format it and telling me that it is two formatters. I'm gonna pick... Okay, not work. But you see like the component shunt name for caching, the pass and the page content, because there is no content here and static query hashes, which you're going to talk about later and you also have the div 404 page, which we are going to talk about later. So, let's create a new file called categories. js I created inside the pages directory and we're going to create here, I react component, I need to import react first and then export. So in order for your page to work, you will have to export that component you have as a default export. So you cannot you cannot use any indexes for export default here. You cannot call it categories page. So I forgot to function. And as we have the develop the children work. So the way this works with that. If you have a phone here called the categories. This would mean that if you go to your website slash. You would go to the right. But what if I write like a very wrong name here? Like something like this so you would get a 404 bitch and you see here. There is a development for orbit that only appears when you are development mode and here if you click on the preview custom 404 page you would get into the actual page we have. And if you click on it, you see that there is no 404 bitch. So let's go ahead and add one. So let's create a new file call it 404 to dress. Let's do the same import yet. So let's go back and refresh this and preview custom 404 page and as you see, we have it here. So that's how easy it is routing is happening or like creating pages in gatsby. So, let's create our header. Let's go ahead and create a folder called components. By source creates a file header. Yes. And then we'd also import the act and here we have the freedom of Exporting either a name to export or a difficult export, but I'm going to use different export for just consistency. So export default. I'm gonna get the return here. So yeah, it's all. Head attack. I've lost me. either. It's a container. And then also create an F container. And here we have our H1. It's also a class name for it. What is our local? And then we add to stay in my game upwards. and then We would also刨 I'm pretty sure for each nav element which create a tag First, we add tref equal to slash and then we call this one hole. Let's copy and paste it. Here you see, yeah, it's like Alt Shift F for the coming down thing. And here we're gonna create 0.4 categories page which we created. But here, we're gonna put the right URL, so, yeah. So, yeah. And to reuse this, we're gonna, let's close this public directory. Let's go to the index page and create a fragment. Fragment here, put the header net and set those. So, that's it. Let's go ahead.
5. Exploring Homepage and Styling
6. Adding Active Class and Creating Layout Component
We add an active class name property to highlight the active link in the navigation. We can also use partial support to match anything after a specific category. We create a layout component to reuse the header in multiple places. We add a link to the logo to navigate to the home page. We create a footer and demonstrate how layouts can be used. We create a Jumptron component for the main banner on the homepage.
We also have phone and categories. As we also mentioned that the active class here need to be added. So we only need it, we only need to add it for the link when it's active. So to do this, there is a property you can pass called active class name, and then you can pass classes. dot, what was it? Active. There are also a lot of stuff that you can do with this.
For example, there is another property called the partial support or something, that would, and instead of like having on the, so if now the active one would work only if you are in the categories page, but if you are for example, in category slash something, it wouldn't work. But if you enable this blank, it will work for anything that has this category. So it would be instead of having to be equal, it will be a match, anything after this.
You see, when we added this, the home is highlighted. If we click on categories, yeah, it should be highlighted, but there is no header here. So let's go ahead and add it. So fragment, header, self close, close fragment. And then you go here. Yeah, you see we are in the categories, home categories, and it's still highlighted. So let's go ahead and do two things. First thing is, let's add a link to the logo because I don't like it when you just, yeah, if you click on the logo, you'll expect to go to the home page. So let's add it. I don't even think we need anything here. So we need to add Zer2 and water slash. And now if you go to categories and click on the logo, you will go to the home. And the other thing is that since we are using the header and both the apps and you are intending to do it, to use it in multiple places, so let's go ahead and create a layout. So you can for example, create a layout directory and create a component in it. Or we can just create another component, but let's go and stick with what we created. It doesn't make a difference. It's depends on your own preference.
So we're gonna create a layout import. It's also React component, so we have to import React. And then export. Okay. So you can also import, export and import here. But yeah, for just consistency we're using. So the only place that you will need to export the component as default is our pages. And then we will call this layout. Yeah, return. We're gonna use the fragment we created and then use the header. So let's also do, so let's first make sure it's working. So we'd go to the index page and then we'd replace this with the layout. And then we've got something here like, yeah, here's the homepage. And you would put all the content you would need here later. So here we are on the home page but the content is not there. So the layout did work but it did not manage to add the content here. So how do we do this? It's normally an idea I can think where you have a children property as to any component. And then you can, put it here and what, yeah, have all the children pass to this to be added into the children here. Let's also go ahead and create a footer. So I'm gonna create a footer tag. Just a second. So just trying to find that text. It's pretty much dummy text. Let's just put it here. And since it's pretty much static, I don't want to create another component. I just wanted to show you how a footer can be added or like how a layout can be used. And if you go to categories, there is no content here. Yeah, we didn't actually add the categories page here. So let's remove this. It's also used layout. And skip adding to content. Let's remove this import. Let's also remove this imports. And you can also take the chance and remove this from here and put it in the layout. Just need to import or to change... Yeah, it's the same spectrum. So now we're in categories. Here is home categories and it's working. Let's go ahead and create a Jumptron. So a Jumptron component is like the main banner you would see in the homepage that have like a title and a call to action button or something. So let's also create this. Create a new file. Also, I react components. Sorry about all of these reacts components.
7. Adding Jumbotron Component and Styling
The Jumbotron component is added to the index page with a background image, title, description, and a link to the categories page. The CSS module for the Jumbotron is used to style the background, content, and text container. The text container is adjusted to improve the layout. Clicking on the categories link takes you to the corresponding page. This marks the completion of the initial setup for Gatsby.
So this will hold, it was for get function. So basically what the Jumptron will contain is let's a return section of this section tag. Oh. So the image, which will be our background, that's oscillators in the name, create a dev. Let's create a container for the text. And then let's add our content. So, let's write some title like, let's add Need some help. This is and for the description, let's add some Laura Lobson, and let's show the first word, that's a lot. Let's try 20. Put this here. And we will also need to add a link to categories, show our code collections that we mentioned in the first slash. So now we have our Jumbotron. Let's just go ahead and add it to the index page because we need it only on the index page. So, I'll start here. Something not working. So link is not defined in component shell Jumbotron. Yeah, link is not outputted. So let's go ahead and input it. And then we have our home page. Here that's our Jumbotron text. And it is the button that would go to the categories page. So first we need to add the image. So let's upload an image here. That's the image we're going to use. Let's go back to the Jumbotron component and change the source to be. So remember what we said about the static asset that we will just use it. So we will just use it like this. So it would be old Jumbotron in. Also asks us for an alt, alt the property so that's yeah, Jumbotron. So you see now it's here, it's loaded, but this time is not correct. So let's add another CSS module for Jumbotron. CSS. And let's find a style here. Let's stick here. So we have Jumbotron. We have the background, the content, and the text container. And we have like a very neat trick here with the display here is dread and for both the background and the content we're using grid area one on one. So it will be on top of each other. And if you go back and refresh. Did not work because we can actually add it here. So import star S. Classes from jumbotron.module.css. Yeah so let's also really like refresh or remove all of these to be classes. Here's for the background we need also. Class background, content same. And I think that's it. We have no other style, let's go back and refresh and we see we have everything we need. What I feel like need some help here is a little bit down so let's first of all find text container and now the text container it's the content. It has a bad link on 30, let's make this a little lower. So the reason let's change it here to be 100. I still found it 30, and that should look nicer. So if you click on the categories here, this also is the same mask clicking on the categories. It's the same link so you would go to it. I think we have like everything we need to start diving into Gatsby a little bit more.
8. Introduction to Gatsby Content Mesh
Let's talk about Gatsby content mesh, which is a GraphQL layer that allows you to add any source you want, such as an API, file system, or database, and configure it to attach the data. This data is then available in one place for querying. It provides a centralized and versatile solution.
So up until now, what we did was mostly React. So let's change context a little bit and go back to the slides where we have something called Gatsby content mesh. So what's Gatsby content mesh? So Gatsby is built over React and GraphQL. And GraphQL is a query for your API. I'm gonna talk about it in a moment but like this GraphQL layer is called content mesh where you can add anything you want, any source you want, like an API or a file system or a database or whatever you want into this configure this layer to attach this data into it. And then you will have it in one place where you will be querying from it. Like it's just one place and use it everywhere.
9. Introduction to Gatsby Content Mesh and GraphQL
Gatsby collects data configured in a single GraphQL interface called content mesh. GraphQL is a query language for APIs. Gatsby provides a tool called GraphQL to interact with the configured content. The Gatsby config file allows configuration of site metadata. Running Gatsby may be necessary after adding plugins. The site metadata can be accessed using GraphQL queries. Data can be accessed in components using the 'data' property. Running 'Gatsby develop' is necessary to see the GraphQL link.
So yeah, so Gatsby collects everything you configure it to collect and bought it in a single GraphQL interface called content mesh but like what's GraphQL? Let's go and go to the website of GraphQL. So GraphQL basically is a query for your API. So if you have an API call, it would look like a database query but you can do it for API. Like for example here, like you describe your data that you will need a name, a tagline, and a contributor, ask for what you want. So I wanna for project, I wanna filter find the project with the name of GraphQL and gives the tagline. And you see that the project that has a name with line and that's what you get. So you get object, as you see, it looks exactly the same as what you asked for. There is also a very nice example here where it shows you every time you change the query like in the top it's a query and here is the result you get you get the exact result you want. And also Gatsby gives us a very nice tool called, yeah, it's not here anymore but if you run it, you will get it. It's called GraphQL which is a pretty nice name. So let's graphQL, And this is a tool to play around with all the graphQL content that Gatsby has built for or like has been configured for like here we didn't configure it yet but we have some stuff that we can find for for example, there is a site or all sites. So let's query for all site. Anything like this tool, you would pick whatever you want that would be reflected here but you can also change stuff here. So let's go for all site and we want to find nodes. We want to find the ID and host and report. So host here should be local host and the port should be 8000. So if you click on play here or run, it will execute the query and you would see what exactly you would see, what you would get. You see like data is the main parent of all the data you would get. And then you have all site, you have nodes and then you have the ID host and port. You can even filter stuff like with, for example if I want to change it to ID equal site, it will still work or it didn't work but this here is the work case and yeah, you can see what I mean by this. But what if I want to change stuff? So remember this file called Gatsby config? Here there is something here called site metadata that you can put whatever you want here. So like for example, a title of every single thing. Like for example, a title. No need. Don't can't hear the title. Should be neat. And description. Okay. Let's get that content we have. But then comma here. That's it. So something very important about the Gatsby content file that this file is configuring the whole Gatsby thing. And even especially after you add a bunch of plugins that we will get into later. It's very hard for you to afford Gatsby to figure this. So sometimes you will need to rerun Gatsby to develop to make it work. But I think for this, we should be fine. So let's refresh and you'll see like this site metadata actually. Do I have a typo? Yeah. I do have a typo here. Let's go back and refresh this. Here you have the site metadata. You can also have the title name inscription. You see like this is a filter, but we don't want a filter. So let's remove the filters, remove also the node. Yeah. For node, we just need title, name, title, description. And since we have only one website, so you see like if we do this, we will get an array of nodes, but we don't wanna do this. We just wanna get our site. So let's create site. Site metadata, so that's also the filter. Site metadata, name, title, inscription. So if you ask for a site or one thing, so we can ask for all things and filter, or you can just ask for one thing. And if you ask for one thing without passing any filter or like a match, you would get the first thing. And then you would run, and here we have what we have. Like, how can we use this in Tides app? So, we're gonna go back to the index page. And the reason why we have to export certain stuff from here is that Gatsby works with this. So for queries, for example, you would just need to export an end variable called query, and then you use the GraphQL function provided by Gatsby to just paste your query here. Let's name this homepage query. You don't have to name it, but yes, it's nice to have it there. And how do we access this data? You would go to Home here, and you would have this as data. Remember when we showed you here that the data's coming out? So yeah, it's passed as a property called data. And then for example, page one here can be data.site. Data.site. Name. And then you go back, you refresh. Yeah, you see, cannot query field name, type site, media, site site, media, data. Why is that different? Yes, because that's what I just said. You need to run Gatsby developer game. So IBM start. You see now we actually can see the GraphQL link.
10. Using Static Queries and Plugins in Gatsby
We use the static query hook to fetch data and display it in components. Gatsby provides a wide range of plugins, such as the Gatsby plugin image, which optimizes images. We can add plugins to the Gatsby config file and install them using npm. The Gatsby CLI can be used to run the development server. Gatsby supports static and dynamic images, which can be sourced from GraphQL queries.
So we have to open, so let's refresh. And here we have the name of the moat. We created for the name, right? Yeah. So how can we use this? So for example, in the header here, we wanna use this as a text and for the jumper tool we wanna change this two. So let's remove this because we don't need it anymore. This is how it works for pages. How it works for components is a little bit different. So we have, there is a static a query hook, you can use a static query that comes also with Gatsby where you would do the same thing you did. So the graph QL and then you would paste the query you want and here. And in here we are only interested about the name. So let's move this or let's remove it there because we will reuse this. So we're gonna run the query we want and then we also have data sites. So let's see what the title and description since we don't need it so something wrong here. So we can just use the name here and the scheduling bits year. It's the thing that we don't need and then we go back in the fresh. Custom role and properties and we'll define the credits. I think what we have wrong here is that there is no data. Let's see. Yeah, so there's no data so we just get what you get here. Get what you ask for. So let's do the same, let's copy this and open on the jump-out component. We need to import these two, static query and character. But here we have the title and description. We're not interested in the name anymore. And this component title and description. So you can see here that I'm using queries that are not named which is okay. So let's use the title here and let's use the description. And go back, yeah, I think it's working.
So let's talk a little bit about plugins. So Gatsby provides us with a lot of plugins that we can use. So let's search for, let's go to the Gatsby website and open source plug-ins. So start our themes, yeah, Gatsby plugins. So for example one of the most important plugins are the image. So let's search for Gatsby plugin image. I have it straight in wrong, Gatsby plugin image. And yeah, you see like the whole documentation of it. So to use image you need to use these two because a plugin sharp and transformer sharp would optimize the images. So instead of having a static image it would generate multiple sizes and do some blurring effects and stuff like this. So let's go ahead and add these into our Gatsby config. So Gatsby config.js and the actual plugins. But yeah, we need to also do install this. So let's cancel this and then install Gatsby plugin. So allow. So now that we have transformer sharp let's install these. So the good thing, oh sorry, something wrong here. Yeah, I have the name wrong. So, yeah. So this get bot tool provides you with like a whole container that you can play around with. So you get an actual terminal on an environment. This is like all of the other tools or like most of the... Also have a typo and it can't be like an image. That I fixed it, right? I think that's the one I fixed, yeah. Yeah, thank you. So now we installed it we just need to run npm run develop. Or start, yeah, as we showed like, if we are the same or you can, if you have the Gatsby CLI you can just try Gatsby develop. Just need to make sure that the globally installed Gatsby library is the same version or like it works with what you have on the app. So building the development and should be working. So let's go ahead and use it. And if you go here, you will see that there's two types of images, there is static image that you can just use like as a placement for the normal image, or there is dynamic, just the dynamic images that you can get from GraphQL. So let's go ahead and try out the first one. We had this Jumbo-tron image here, but to do this, let's move this from static here to add a new folder called images. And then I'm gonna move this here and then we're gonna use the other component called static image. And it has also a source and all that supports everything you can pass here and should be working. You see like now it's not working. Yeah, because I changed it. So the source here is relative because Gatsby takes care of loading this one and changing it out of the box. So images slash domain. And you see like here, every time you refresh, it has like a blur effect. And the background here, it's keep it from just for you to see it. The background here is a preloader background that you can do everything you want, like resizing, cropping, changing the quality or whatever you want here, which is a pretty nice thing.
11. Adding Actual Content and Configuring Plugins
So let's go ahead and add some actual content. Let's create that category component. We would need two plugins, one called Gatsby transformer, and other one is called Gatsby source file system that allows you to add file system into Gatsby layer. So let's add a Gatsby source file system with the name 'categories' and the path as a template string. Create a new file called 'first.md' with the front matter including a title and category slug. Use a tool like lorem markdown to generate some markdown content. The Gatsby source file system plugin imports the categories directory and the Gatsby transformer remark plugin treats the markdown file differently and generates useful stuff from it.
So static image. So yeah, that's basically how the plugin image work. So let's go ahead and add some actual content. Let's create that category component. Alright let's first show you how it's loading files and then we can talk about category. So let's install that needed plugins first.
So in Gatsby config, we would need two plugins, one called Gatsby transformer, and other one is called, which is a pretty important one. It's called Gatsby source file system that allows you to add file system into Gatsby layer. Sorry, the GraphQL layer. And there's two ways to add plugins. Just this text one, which will be resolved and other one that's configured. So here, we're gonna add a result. So we're gonna add a Gatsby source file system. And I'll use this later. And we have options. I remember the options. So let's check them out. Source file system, yeah. So you see it has the name and the path. And the name is used to distinguish multiple sources. So name here it will be categories. And we have the pass, which is, is a template string. There's source. So let's go ahead and create this directory. New, and get it on file. But yeah, let's first install this. So let's start this, cancel this. I'm gonna be able to store for this and gets the source file system. And while it's running, let's create a new file here called first. So MD here stands for Markdown. Make sure I have another title. Sorry about that, source file system. And so we have the first category, the markdown file. So what's a markdown file? It's a type of a rich text document. If you are not aware about it, you can just check markdown and you will see a lot of guides here that will allow you. So the markdown looks like this. Let me show you how it looks. So if you put like a hash for example, then you have a title and h1. And if you have, yeah, if you put like two hashes, that's h2. I think three stars. Or italic, two stars, r bold. Yeah, so basically something like this. But also have a very important thing called front matter, which are pretty meta stuff for your file so let's add a title here. First category, category slug which will be our unique name for the category to create with. And then you want to add some content so it is a pretty nice tool for this called lorem markdown, something like this. Yeah so this tool you can just generate some markdown and then you'll get all of this content. But you are not interested in all of this because for categories we just need some small content. So advanced settings here. With number of blocks to convert to one, generate and here you have a bunch of content. Let's use an H2 because we don't want to have an H1 appearing on our website, or H3 even H3. So if we run now npm run develop. So we will have two things to have. So first the gatsby-source files system would import our categories directories. So first it's all the files category, as files and then our Gatsby transformer remark. The other plugin would detect that this site, this file is a markdown file and then treated differently and generate some useful stuff from it. So let's go ahead and get being to refresh. And you see here we have all file. So let's run all file. And then you have the ID. That's good for nodes. And then you would have the ID. You will have something here called child markdown remarks. So that's basically, if there is a markdown remark in this file, it will be created here. So let's check the front matter. And here we have this plugin title. So let's go ahead and see this. And you have the first category. You can also find something very interesting here called source instance name, which we mentioned earlier, that would be our way to filter types because later we'd be adding articles and we wanna distinguish these from those. So yeah, we usually use it as a filter. So yeah, that's how it works.
12. Creating Category UI and Querying Data
In this part, we create the actual UI for the category section. We add a container section with a header, title, and description. We create a category card component that includes the title, excerpt, and a link to the actual category. We add styles for the category component using a CSS module. We use a query to generate a list of categories on the homepage. We filter the data to only include categories and format the excerpt to be plain text. Finally, we map over the categories and pass the category object to the category card component.
So let's leave this as it is for now. Go ahead, go back and create the actual UI for it. So from now on, I'm gonna try to make the UI takes less time, so I'm gonna try to paste more stuff, but if you have like any questions, please stop me because it feels like I'm wasting some time here.
So here we have the jump button, which we don't need any more. And then we would need a category section. So let's go ahead and copy and paste some CSS, some HTML string, move this. And here you have like a container section header, title and description was explore our categories. We go back and refresh. You'll see it like this here. We just need to add our cards, or the category cards. So let's create a component, build category, to JS, which is basically a category card. Let's copy and paste same words. It's giving me time. Export default function. Export default function. So I'm gonna try to make this shorter, plus name category, and category and then h3, which will contain the title, etag paragraph tag, which will contain the excerpt. I think this is where... Hopefully, I said it right, and then the link to the actual category. So which would be here in this case, categories slash slug, which we will get later, and then close it, type read, and that's it. Let's before doing this, let's return, no it's complaining. Okay, so now let's go, and also add the styles. So category, module.css, yeah, I have it here. So I'm gonna create the file, new file. And then,iguous. And moot it here. Yes. Oh, do I have only one crossword question? Oops. No capital C, let's change this. And yeah, nothing here because I haven't added to the index yet. So here's action header, I think I should add it. Sorry, just a second. So yeah, I'm gonna also add another cross here. Another container here called categories. Then add a category component. So it's imported, it's working, but it's complaining about the link. It looks like it didn't import it. So I'm importing it. Does this work, okay? Come back, fresh, and here we have the title, which I'll add in the read more. Of course if we click on this, we will get a 404 because we haven't created this file yet, but yeah, it's just nice to see the actual URL. And then I'm gonna go back to the categories to the homepage. So let's use the query we created to generate a bunch of categories, codes. So to do this, we're gonna make sure we're going for to all file. But here, the important part, we remember we only get the categories. So we wanna filter with the source name. So we're gonna go ahead, find source instance name to equal categories. Now we're not interested in source instance name anymore, and I'm gonna call this categories. So that's how you rename variables. So now it was all file, now it will be categories. So I'm gonna click on this and here I have a bunch of categories. So I have the titles, the slug, and this takes us to the excerpt. So if you don't know what excerpts means, it's like the short version of your content. The format should be plain, we don't want HTML, this should be like 150 letters and truncate it to be true, and then go ahead and do it, and yeah, you see. Like, it's taking from the HTML, because if you look at this HTML thing, it's the whole content, but this is like cutting the HTML a little bit. So we are interested in this, only in this for the categories. So you're gonna take this query. Go into the index page where we need it, and then export const query for lf, lb. Variable that's this, and we can call this query. And yeah, as we said before, now we have our data. So instead of using it like this, of course we need to map something to it. So we're gonna go over the data.categories.nodes and that's the array we have. And then we're gonna create a map. The map will contain an ID and a child, down to the framework. And then I'm gonna go convert it into a category tag. Let's add the key, which is our ID and then pass the category object to the component. It's not expecting it yet, but let's go ahead and pass it. So child markdown.remark and let's close tag. And it should work. Let's see if it works. So yeah, since we only have one file, it's looking like this, but it's working. Now that it didn't complain.
13. Adding Data and Images to Categories
In this section, we are going to add the necessary code to display the data we passed in the previous section. We will convert the font matter and slug to be used as a title and slug respectively. We will also add an image to the category using an icon. The icon will be treated as an image object instead of a plain text string. We will use the Gatsby image data and the dynamic image component from Gatsby image to display the image. Finally, we will upload a bunch of categories and verify that the data is displayed correctly.
But as you see the data we are passing here is not used yet. So we are gonna go back into our component. Expect the child down remark here, which is called the category. And if we go back here, you will see that it has a font matter, title, slug, and text. So this one will be font matter. Slug. And also we have serv. So, yeah. Let's convert this to a title, convert this slug. Sorry, let's make this slug sort. And for this, we wanna change this into a template string. So it should be like this. This should work unless I broke something. I think this should work. Thank you too. Yeah, I don't have an ending for the console. Go back and refresh. Something is not working. Function swap from to matter. I think this doesn't have the capital M in the middle. If you wanna make sure you can just go ahead and ship the query. It's easier this way. So now we have the actual content. The first category that style. But yeah, if you click here, you'll see that it's going to first category. It's not working yet, but you have the right slot. So let's add an image to our category. So to do this you will need to add image, something like an icon, and also show you how the queries work. Let's first upload the icons on your folder, icons, I'm gonna upload a bunch of icons here, icons and then you have this. Go back to the first category and here the link should be relative from here. So images, icons, slash, for example, complain. Go here and refresh it. You'll see that for the front matter, so child markdown remark that is for the front matter, it's still an icon. Yeah, so why it's still so the icon here, it's still a string. Why it's still a string? Because remember when we were talking about here, so we added the source file system to this directory or we didn't add it to the directory of images. So now we wanna add it to the directory of images, so let's call this images. So now every time a string would reflect a link that looks like this, it will be treated as an image and then I'm not sure if it will work, so let's read on it. But now like this, icon will be an image object. Not just a plain text as you see here. Did I miss something? You're missing a closing tick. Yeah, thanks Dev. So now should be working. We haven't changed anything here, so let's go to Icon and you see the icon opened. So there's a child image sharp. And what are we important in here And interested in here is the Gatsby image data. You can put a lot of stuff here, like for example, you can put the widths to be 64 pixel. You can make the layout to be constrained or whatever you want. Or then you have this icon that you can use. So I'm gonna go ahead and use it. So to use this, we need to go to first to the index to add it to the query. So here. And then I'm gonna also use it inside the category. So I also know that I have an icon here. So let's add an image. So here we are going to use our dynamic image component from Gatsby image. And we're gonna pass the image to it. Let's see how we are going to pass it and then give it class name of process icon. So there is two ways to pass the image here. You can just go icon and then child image sharp and that gives the Gatsby image data or there's a helper function from Gatsby called get image from Gatsby plugin image so that you can pass the container and then it would work. So let's see if it works. Push and here you go. You can also see it's loading and has a background and everything. So now we have our first category. Let's go ahead and upload a bunch of categories. So I'm gonna delete this one. Delete permanently, upload and then go back to the workshop. We have our categories. I just a bunch of categories that they added. It all looks the same. But here if you refresh, you see that we have actual data that can work and with even different links.
14. Creating Category Page and Querying Data
So our next step would be to create the category page and then use Gatsby to generate multiple category pages for every category. We will name this query 'query' and query for the category itself. To create the page itself, we're gonna return the normal layout. We add a section, container, section header, h2, and b tag. Then we add a bunch of articles and create the article itself.
So yeah, basically that's how Gatsby and GraphQL works out of the box. So our next step would be how we are going to generate this. So, the next step here would be to create the category page and then use Gatsby to generate multiple category pages for every category. So first let's go ahead and create the category page. And to do this we would need a template. So let's first create it as a normal page and then we would move it to template.
So, a new file here. Tutorials. Yes. Of course, we do it. Okay. So, since we have a query, then we're just go to data, and then let's first prepare the query. So, export. So, let's try to type our own query. So, so we will name this query let's name it, query. And then first we are going to query for the category itself. So, we're going to go for, since we know the slug of the query, so we don't have to go from the file. So, we can just go for all mark, dummy mark. So, or is a mark, dummy mark, because yeah, we know what we want. So, mark, dumby mark. And we gonna filter it by font matter. And the slug to equal, we could use one of our pre-created creator, so we'll reuse Adding Content. And slug should be adding content, and we're going to open this, back to Title, and if we go back to the one step back, we also need the title and the HTML. So that's basically what we need, and area-creator-input and linkage because I need to... Use it work. Okay, so let's see why it's not working, let's take it to the Gatsby, try to unmute, here is it, yes, look it's not I think it's because I don't have equal, yeah. So I have to have equal there. Double quotes. It should work. It is not equal. So, now it should work. So yeah, let's take this. Take it back, put it here. And also let's name this, because we're gonna query for articles later.
So to create the page itself, we're gonna return the normal layout. Why it's not loading? Gives me imports. Layout. From, back, unpicked, go back unpicked, slash, and this should go. And so for this we need a filter, so let's add this slug. In our case it's slug, and it should be string. And then for this, we can remove the adding content, so reuse the slug. So if there is no context here, I think back what here will be the first one. I'm not sure, let me see. I think if this is empty, it should get the first one anyway. Yeah. So let's use it like this for now, and I'm going to show you how we mess this here. So layout, let's create section here. Get the container. Add the section header. And h2. So data here should have categories. And here categories, sorry, not categories, category, one category. And then for the h2 here, it would be category.font, dot font matter. And then I'm gonna add a b tag here. And for the b tag, we need the HTML. So, and to add actual HTML, you need to do something different. So there's a property here called dinges.list.setHTML. And then you pass a property, HTML. And then you give it a category or HTML. This should work. So... Oh yeah, at this point, this one would work like this. And you see it has HTML and it has added content and everything. Let's make this one a line lift. So style, text align. And then it should work. All right, let's add a bunch of articles. But first, let's add like how the article would look and then create the article itself. So, we would create the link. Cause like the whole thing would be a link.
15. Creating Article Template and Generating Files
We add a static image with a plus new particle icon. We add articles to the Gatsby config file and filter them based on category. We have a bunch of articles added to the adding content category. We only need the title and slug for the articles. We create a template directory and a gatsby-node.js file to generate files using create pages.
And class name. And here... Link... Would go through... The slug which we also will get to generate into later. Close this, and then let's add the new... Let's have the image here. No, let's just find this here and copy and paste it. Okay... I'm just going to paste a bunch of HTML here. Okay, finished. So, yeah, I just added a static image with a plus new particle icon. And all right, so let's do this twice, when I remove it, but just to see if it's actually working or not. I see that static image is not imported. And link, I think? I'm not sure why link doesn't get imported automatically. Let's see if it works now. Title. Yeah, because. So now we have the actual two articles, and if you click here, you have articles slash slot, but that didn't work. And we need also to add, let's first make it one. And then I'm going to show you how it works with this article. So for articles we're gonna do the same thing, to add a bunch of articles, all we need to do is go to gatsby-config, add another source here for articles. We're gonna go ahead, okay. Renew directory. I'm gonna upload a bunch of articles. I think it is, it's the articles. I have a bunch of files here. And for articles it's different because we have the category, so which we use to filter the articles based on the category. And then we add this. We just need to stop this and run it again. You see the articles query. It's got USB. Does it work? Not yet. Okay. All right. So now we wanna go for old file and find, sorry for filter, we wanna filter it by articles. And then we're gonna run it and you see, we have a bunch of articles here. Yeah, but we don't need this anymore, we don't need this right now because we know that we wanna filter by categories, so we wanna go to old markdown remark. And then for filter, we were going to format category, equal and then pass for example, adding content here. That's what we wanted to do. And then, yeah, slug is still here but we will change it later. Let's remove this. We have a bunch of articles added to the adding content category for the articles we are interested in. The HTML, no, here we are only interested in the title for no matter we need the title. And this slug, that's all what we need here. So we're gonna name this articles. And you wanna take this, sorry. I'm gonna take all of this and put it on the category page. So we also need this articles on macro equal and here we will replace adding content to have also the slug of that category. And for this, we are gonna I have a category here we also need to charge that. So we need to move over our articles. I also need the ID. First with this, we would need the ID and the font matter. And then we have the title. So title would be here and the link could be used as key here. Sorry, the ID could be used as key. So we have all the articles that we need. That's all the articles because there's actually no Slack. So now we have our template. Let's go ahead and create a directory called templates. So, templates. This one here. So the way to actually generate files is there is a file called gatsby-node.js that you can create. gatsby-node.js. So, that can create. What you can import or export something called create pages. So, these files, these functions you would write here would be exported and gatsby would generate them on the build time. So, we're gonna type an async function. That would take actions. And GraphQL variable.
16. Generating Pages and Introducing Contentful
We run a query to get all the categories and create pages for each category. We generate files using createPage and pass the slug as context. The create pages function gives us actions and GraphQL. We can create a query and generate pages. We can do the same for articles. Now let's talk about a content management system (CMS). A CMS is a database for digital content. It allows you to create models, add data, and query it. A normal CMS has its own frontend, but a Headless CMS provides only an API. Contentful is a modern Headless CMS with an easy UI, GraphQL, and Webhooks. We will create a workspace and a content model in Contentful.
And then we're gonna run the query to get all the categories. So, constant data net weight GraphQL. So, we wanna run a category that will give us all the categories. We are only interested in slug here. So we wanna do this like this. And we just need to add that query. So now we have the categories and then we would get all the slugs we need. And then for the data we get back, so data.nodes. And categories.nodes.forEach, we are gonna create a page for. So actions.createPage, it's a function that gets passed to the function, as you see here. createPage and createPage will take three things. App else, which is basically the route for it. So it will be slash... ... troops. So we'll create a component. Which means the absolute pass, so component here is our template. So we're gonna use pass. Yeah, I need to acquire it. And then we're gonna pass the context. And the context here is the slug, so we will gonna need the slug here. So for nodes, we're gonna have Shile mark, down remark. Shile mark, down remark. And then slug. So now it should work. Let's close this, right again. Top transform the first time. So, what we did here is this create pages is a function that gives you actions graph grl, and then you can create a query here and then do stuff like generate pages or do whatever you want here. Not sure if it did work or not. So let's check out, go back, pick one that not work. So it did not work. I'm not sure why. So slash, categories plus sleight. And component would be, oh yeah, because the component I didn't actually pass the component. So pass that threesome. Then we can look at source slash templates I think, I mean. It's old, yes, I should do template. I'll stop it one more time. Okay. So let's go back refresh and here we go. I have the articles. Yes, you see this file is generated for each category now. Integration does not have anything but getting started doesn't I think clouds ever has. And then you can, you can do the same. You can go ahead and do the same for articles like generate a bunch of articles and then generate pages for them. But I'm not gonna do this here because yeah, we running out of time. So I'm gonna go ahead and skip this creating the articles. It's the same as, as categories. It would be just a redundant work. So I wanna go into the next thing or our next big thing today, which is content. So let's first talk about a content management system. So a content management system or a CMS is, is a database for your digital content. It's a place where you can create models for your data and then add these data and to query them. So a normal CMS would have its own front end. You can do whatever you want But that's basically server-side rendering kind of app that you would get an event and like wordpress. If you have been around for a long time Jumbla and Wix, Wix is a new thing to talk about Jumbla. And with the evolution of single-page applications with most of the CMS not able to provide you with API as there is a new concept came out called Headless CMS which is a normal CMS, but it will give you API instead of actual views or actual UI. So it's a decoupled CMS where CMS provide you with only API that you can consume as any form that application you want such as a web app, mobile app or even an IOT device such as Contentful. And there is also Headless WordPress. And this brings us to Contentful. So Contentful is one of the very modern Headless CMS that provides you with everything you want in a very easy UI. And also provides you with GraphQL, Webhooks and a lot of support out of the box. Let's go ahead and check their website. So the way we are gonna proceed with Contentful is I have two accounts. One that I'm gonna create a workspace right now and I have also one that I pre-created with a bunch of content that we are going to use in our app. So I'm gonna log in with my free account. Also they have a free plan that gives you a lot of, like everything you would need as a normal person, not a team. So yeah, first you need to create the content model you want on kind of design my content model. I'm going to name it category. Yeah.
17. Creating Category and Article in Contentful
And then I'm going to create a field for the category, including a title and slug. I will also add an icon and content. I will create an entry for the category, add the title and content, and upload an image. I will then publish the category. I will also add an article and configure a reference to the category. I will save the article and add content. I can add an existing category or create a new one. I will show you API keys and the different types of Contentful APIs. I will introduce the Gatsby-Source-Contentful plugin and its support for GraphQL. I will answer a question about similar plugins for other frameworks. I will explain how to consume Contentful APIs and the setup process. I will mention code generators for API clients. I will explain the process of adding the plugin and the element space. I will explain the Go step and connects methods for querying. I will copy the connection code and return to my app.
And then I'm going to create it, add a field that starts with text field, title, create. So also add another one. Also on our normal ticket, which is our slug. And for this, I'm gonna click create and configure because I want to change something here. So for validation, I'm gonna make it a in field so that you don't end up with multiple categories with the same slug. And also I'm gonna add the icon, which in this case, a media. And then we're gonna also add content. So, sorry for the content. Yeah, I'm gonna make it text, but here it's a long text, so long text supports Markdown. Then I'm gonna go with content markdown... I can just go with description here. No, let's take was content so that it will be the same as articles. I'm gonna create, then I'm gonna click save, and you go to the content, and then you add the category. So, create an entry for title, and then I stick with what I have, content, let's look, blank spaces, just dashes, add media. I'm gonna add a new media, because we think so, and I'm gonna upload one, select files to upload, and content, I'm gonna use one of the images we have here, so this one. You see, like, you can upload from a bunch of different places. There, it'll click on the embedded storage. There it is. And that works. You can go back to the project to see if there's any content on this file, so I think then we have the link to the project, all the content, and the links. So let me, See, if you have any questions about Contentful, please take a chance, Matt is here, and ask how, like, as many questions as you can. That's a very good chance. And then I'm gonna publish the, and I'm gonna publish it. You can also do the same with articles. So you can add an article, but I wanna, why I wanna add an article here is that I wanna show you a different type, which are relations. So article, create, add field, and also add title. Since I'm not going to use this one, so I'm not gonna, I just wanna go over and show you stuff that we will need. So you see a reference here, which will be called. We're gonna pick one reference and you can configure, that is, except only, yeah, except only subscribe and to type, I'm gonna pick a category, and that's it. So if you wanna add, let's save this first. Go back to content, add an entry. So, article number one. Add content, you see here, I can add an existing content, like this one or I can also have the chance to create a new category on the spot. So now I have that categories and articles. I wanna show you guys something called API keys. But let's first go to the homepage, you see, like it's already there. So for content, for pitching contents there are three different types of APIs. There is a preview API, which will allow you to show stuff that are drafts or not published yet. There is a delivery API that will work only with published stuff. And there is, I think, I'm not sure, it's called Edit API or something. Let's see. Yeah, it's called Management. Management API, which would work. But for our case where you need the space ID and content delivery API. And with Gatsby, there is a plugin out there called, go to Gatsby plugins, it's called Gatsby-Source-Content-Form. And it provides you with everything you would need to contact with Gatsby. It even supports GraphQL out-of-the-box. Gatsby-Content-Form. This one is usually supported and it's very nice. I have worked with it, it's very fast. So for here, you can, I'm looking at the pixel. So is there a similar plugin, maybe to some view-related frameworks like Next? I know that there is. But like Matt, if you want to answer this question, please go ahead. Matt, are you here? Yes, I'm sorry. I'd have to look it up for you, but I'm sure that someone has made a plugin for this. But even if there isn't a plugin, it is incredibly simple to consume either the rest or the GraphQL APIs of Contentful. And the setup for that is fairly easy. What is usually more work are code generators for Open Graph APIs or for GraphQL APIs that do generation of types, generation of API clients. But simply consuming one of the Contentful APIs is incredibly simple, but I'm more than happy to do some research and see what's around in the open source landscape for NERST. Thank you, Matt. So back to what we were doing. So you see the, you would just need to add the plugin, like install this running NPM install and then add it with an element space. So ctuandKclm. So this type of is better seen from desktop. And you say, okay, this has a lot of information. I don't know how much information it has in here, but it says Go step, which is an HTTP for private platforms. And then it says also the connects, which is a query method that we need to run. So it's basically writing messages and we check that and then we say let's use the connection to run it. I'm gonna copy this here. I'm gonna go back to my app.
18. Adding Contentful Integration
Run npm install for it. Copy and paste the data from the other workspace. Check the last branch, forth milestone, gatsby config. Run npm run develop. Switch to the other account. Refresh the page to see Contentful data. Access categories, articles, and related data. Create the category section on the index page. Use Contentful to create the ID, title, slug, icon, and excerpt for each category. Replace the existing code with the Contentful code. Map the nodes to create the category section. Remove the font method and use content field instead. Use Gatsby image data for images. Fix any errors by removing the cache or deleting the public directory.
Run npm install for it. And then I'm gonna go to Gatsby config file. And I'm gonna also add it here. So resolve. And then you have, so I'm gonna copy and paste that data I have, which are pretty different because I added a bunch of content into the other workspace. So gatsby config. Okay, I don't have it here. So I'm gonna check, I have to check the repo. Okay. So, yeah, if you check the last branch, forth milestone, gatsby config, you'd find it. I'm not encouraging anyone to do what I'm doing right now for my account, but yeah, sorry about this. So options, then you've got space ID and X token. So now that it's there, all you need to do is run npm run develop. So I'm gonna go ahead and switch to my other account. So I see, like, I have a bunch of categories here. I also have a bunch of articles that I added, so it would look nice when working with that. So now if you refresh here, it should also have all contentful, like everything that's coming from Contentful. Like assets, articles, categories, and everything out of the box. I haven't done anything. You see, working with file systems is even harder than working with Contentful. So if I click for all Contentful article, I go for nodes and then I get the title, then do this. And you have all the articles you want. And for every node, for node you have the category that you can also check stuff like slug and everything. You can even access the category from the article. So relations here are mostly happening out of the box without you handling it manually compared to Markdown files. So for example, if I wanna go ahead for the, let's start by the index page. And then you see here I'm creating the category. So I wanna do the same. I wanna have the ID, the title, the slug, icon, and the excerpt. So I'm gonna try to do the same for it using Contentful. So we're gonna go for all Contentful categories and then nodes. And we are gonna create a title, the slug, the ID and the Gatsby image. And what was it? I think it's content here. Where's the content? Shadow, file, Gatsby image. Yeah, that's not anything else I could. So yeah, content, content here, and I have the child markdown remark. I'm gonna go for the excerpt, and do the same format, plain, Romlands one 50, truncate to be true. I just wanted to show you how easy it is compared to doing other things. Like if we do this from scratch, it would be easier to have Contentful there from start. But I just wanted to demo how, how you can have like different options other than CMS or Contentful in this case. I'm gonna take this. I'm gonna go back to my home page, and I'm gonna replace this with that. So, now we have categories, nodes, and then we have title, slide ID. So it's different. So nodes map, right now I'm interested on the whole thing. So I'm gonna call it, category. And here, this would be category. But the ID, and then I'm gonna put that would be so, like so for every, yeah, for every node, there is a title, slide ID, icon, and content. I just wanna make sure I remember this when I go to the category. So here we don't need the font method anymore. But for accept, because this is a content, it's called content field, now you have to go over, chind mark, dominant remark. And then you would go for that. And for using it, it's still the same. When you have the categories, titles, accept, and everything we need. And the Gatsby image here would work with the image that's coming from contentful. And then, I'm gonna go here, go knowledge base. Looks like I missed something here. Yes. So, So I'm trying to give it the words for image because I'm guessing the Gatsby image. I think that's where I went wrong. I should go for Gatsby image data, not Gatsby. So yeah. Go back to the index page. Change this to Gatsby image data. It's not completing. So at this point, I want to re-run it to just make sure it's working. So sometimes if stuff like this happens and you don't know what to do, normally removing the cache is the first thing to do. So just run Gatsby develop again. And if the problem's still there, you would just need to remove your public directly, like delete the whole thing. And then, because sometimes the cached files are not working properly and you would end up in a loop errors if you have something you send.
19. Troubleshooting and Final Steps
Errors occurred while working with React components. The Contentful categories and articles are now displayed correctly. We can proceed to add content from Contentful and deploy the project.
Like the errors doesn't make sense. Okay. Let's hope this wasn't. Okay. Objects are not valid as React child. Yeah, so found object tools keys, if you're not running the production, ya. So excerpt here is looking like an object, which shouldn't. That's not, which is weird. Maybe I have something wrong here. I can't contact. Let's go to the category. Yeah, that's the whole thing. So yeah. So you think now it's still working. We have the new articles that's coming from that thing. And these are the contentful categories. So let's do the same for the other query we have. I think we are capable now of editing our category in the page. So let's go ahead and try doing this. So we wanna go to the category template and we wanna change this. So now we wanna have, I don't think I can, let's go back. So we wanna get a category with the slag, the font matter, title and HTML. So we wanna find a contentful category, we wanna filter it with a slug, click on it. And then, let's click on our variable. And then we wanna have the title and the slug, do we need slug, I don't think so. I think we only need the content. And in this case it should, it should find the content, try to mark down the mark and then get the HTML. What we need, title HTML. Let's see. So yeah, title and HTML. So let's replace this with that. And I think I can do the same for this. So contentful. All. Article. Well then we're gonna have this. So. Category. So we'll choose categories here. So, full content of our article, filter, category, slug, equal. That's what we want. So, we've got this. Or equal. And then we would have nodes, and then I'm gonna have the IP title. Yeah, looking good. So now we need to reflect this here. So we have the category, which contains title, content, child, remark. So no front matter here. And for the ID, we have ID and also title in the same place now, in the same level. I think this should work. Let's see. Yeah, I just need to regenerate the files now. So I have to run npm run develop. I'm not sure if regenerating the files would need this or not. Like you need to run npm run develop multiple times or it doesn't take care of it. So you see now it has the actual articles that we need. Of course we don't need the articles files. That's why it's not working, but you see how easy it is to configure it. Now we go for adding content. Then you have all the content you need. This content is all coming from Contentful. Yeah. I think that's basically it for the Contentful Gatsby thing. I think the only thing that we need to do right now is deploying that. Let's take a five-minute break here. I still be there to answer questions, but if you want to go... So it's a Q and A for five minutes if someone wants to answer a question. I'm not sure about these questions in the chat. I think Matt answered all of them, but, yeah, Matt, if you want to answer something or elaborate on one of these questions, please go ahead. Sure, yeah, sure.
Deploying App to AWS and Setting up Hooks
Contentful supports versioning and different environments. Version history is maintained for every entry, allowing rollback and comparison of versions. Contentful offers the environment feature, allowing the creation of develop or staging environments. These environments can be consumed using the API endpoints. You can build static pages in Contentful and render them on Next.js pages. Tutorials and starter kits are available. The last part focuses on deploying the app into AWS and setting up hooks for automatic redeployment when pushing content to GitHub or making edits in Contentful.
So, yeah, two of the questions that we got is, does Contentful support versioning or version history? And it does. So, for every entry that you see, and an entry is an instantiation of a content model. So if you can see here in the screen right now, you see a content entry on the right, you see CD versions. The versions are maintained by the moment that they are saved. And they are maintained by all the users. So you can see all the different versions by all the different users that you have. So if you would make a change here, you would see the different versions on the right side. And you can either roll back to an older version or you can even compare two versions with each other, which will show you a diff view per field. So if you would now click the compare with current version, you would get a diff layout. And you could change what fields you want to roll back. So none of your content goes to waste. Your versioning remains the same.
And another question that we've got is, does Contentful support different environments? So as you mentioned before, we have the preview API, which can return you data that is in drafts. And we have the delivery API, which will return you published content. So in terms of environments, we offer the environment feature. So if you would go to settings, environment, you can see how you make an environment there. So an environment here is basically an environment for the models that you have created. So by default, all your content models are created in a master environment. But you could make the decision here to make a develop or a staging environment. This is especially useful if you are still actively developing while content managers are already filling content in the content models. And you want to avoid conflicts or broken development interfaces. So an environment that you're creating content from now will be a carbon copy of the environment at the moment of creation. So this makes it very powerful to also make backups, for example. So if you have a master environment and you want to create a backup, just pick a moment in time. You create the environment. You have a backup of your environment at that moment. And these environments can be consumed by appending the API endpoints that you are consuming. So if you would be using the delivery API, you would simply append in the URL after the space ID slash environments slash the name of your environment. And then you can consume either data from the production environment or data from the developed environment. And they both use the same API key. It's also possible to set up an API key per environment if you want that.
All right. Thanks, Matt, like, yeah, yeah. I do like your answers for all the question, like, you go and it operates and everything. And I think your answers are pretty much satisfying. Thank you. So let's go ahead with our last part here. So in our last part here, we want to deploy our app into AWS and then set up a bunch of hooks that would make sure every time we push our content into GitHub, the deployment will redeploy, the app will be redeployed and also set up a hook on Contentful that would do the same. So every time you edit an entry or do whatever you want or do something, edits on the app, also it will trigger a deployment. So in this way you would make sure that your app is always up to date. So imagine you have like a content team because the main purpose of having Contentful or hidden CMS is to have like a content team working on editing stuff and their stuff would get redeployed instantly without the developers triggering deployment or doing anything. So this way you decoupled that development from the actual content and you can deliver a very efficient and performant static website like a web logo or whatever. So let's go ahead so let's... First I have like, so the first thing I shared with you guys here, I have four branches and this branch is a fourth milestone which has everything ready. I'm gonna check it out here. So I'm gonna roll back everything. So I got 44 files and then I'm gonna switch to fourth milestone which have everything ready. I also wanna show you something like how it would look if we finished everything. I think we would need to restart the development. We also might need to uninstall first. Yeah, this also will show you that you can have the markdown file as the whole page. You don't have to use it on the description or something because you will see here in the articles that we have a page for every article that has the whole thing. So you can basically keep going on Contentful and create a model that has a title, slog and content and do whatever you want and then query it to wherever you want. And then put it in a page, put it in a card or wherever you want. So let's go ahead and go into our page and refresh it. It's still the same thing, but yeah, pretty much advanced, so let's go into adding content and then click on this. And here you have, like this is a title of the article. This is the whole content.
Deploying Web Projects with AWS and Contentful
To deploy the website on AWS Amplify, sign into the AWS console and select AWS Amplify. Connect to the Git repository and click next, save, and deploy. The build process will clone the repository and provision the environment. The frontend assets will be generated, including HTML files for the category template and articles. To fix self-hosted images, modify the rewrites and redirects to include the webp format. Explore the deployed website and add a webhook in Contentful to trigger redeployment on AWS. Create the webhook in the bill settings and define the execution when the API is called.
And here you have, like this is a title of the article. This is the whole content. You can put as much content you want here. You can even use, navigation, sorry, imagination or infinite loading or stuff like this. It's all down out of the box where it gets the uncontentful.
All right, so let's go ahead and deploy our website. So I'm gonna go for AWS and then you would see sign into the console. Of course you can create your free user, your free tier user. And yeah, so I'm in the console of AWS. I have a lot of apps here, but we are interested in AWS Amplify. And because I opened it before it's here, but you can just go ahead and search for it. And it's pretty much straight forward. So you're getting, get started. You'll find that this one will be hosted on Amplify. You just need to connect to the get repository to continuously deploy your front end and the back end, get started, get up. If it's your first time, you'll get to authorize stuff, but because I've been here before, it's easy for me do, so yeah. And then I get a bunch of the repos. I have this repo already, and then I'm gonna select this branch. And then you can also see that there is a way to support Minorep, Minorepos where you can just pick a folder and then go from there. But here this should do, and the default build that's auto-detected will still work for us, and then we're gonna click next, and then save and deploy. This will take a couple of minutes to get, so it's like it ramps up a whole environment for you and it deployed the app. And build the app and do everything you want. And so for Hux, for GitHub there's nothing you should do here because it's already set up. So every time right now you generate something or you push something into this fourth milestone branch, it will be built automatically. So I'm gonna see that so it's still in progression stage. Just wait for it, it should take like five minutes maximum. Also one of the good things about Gatsby that you might think that because we are generating like thousands of HTML files at load for a very big app. It would take a lot of time, but the good thing is that everything is cached and when Gatsby regenerates the file that the old app, it will only go and build the only stuff that needs to be redeployed, like stuff that had changes in files, stuff like this. And this way, like the next build would be faster and faster and keeps going. Now it's cloning the repo. All right. All right, so most of the time here, it's not the actual build, the build is still cloning the repo. I can't see the screen. It's still cloning the repo and going over the provisioning and like rounding up the environment. But do you see that the build itself is very fast? There's also a bunch of interesting stuff here that you can, for example, remember when we talked about environment variables, here you have environment variables that you can add and it will be added to the process. So you don't even have to support the dot M file there. You can just add the environment variables here in the deployment. So the backend was passed because we don't have a backend and here's the actual frontend that's happening. Okay. I see like here it's telling you that there are six new assets, there are 23 new entries and 12 big entries. That's what I was trying to say. So you see like here it compares the previous version with the new version. And it's only like adds a modified stuff. Like for example, some stuff are cached and some stuff are not, of course, because it's the first one it's nothing cached yet. And you see here for the category template, it actually generated six files, there's one and five more, and for articles it generated all the files, the 404 page and then the same HTML. I think it's done already. Yeah, so now if you click on this link, it would work. So one of the things that's really interesting here is that why is this image not visible? Also if you, yeah, why this one not visible? This is the only, like to think of it, this and those images, I'm gonna find any content, are the only images that are self hosted, are not coming from Contentful. So, and to fix this, if you go to rewrites and redirects, you'll see that all the URLs that does not end with CSS Jeff and all of these files will get rewrited into indexed HTML. So we need to change this. Go to it, and because, gets the image sharp, what change the blog chart, what changed the images or like enhance them into the web B format. So we need just to add the web B format here. And save, go back here, refresh, explore categories. Yeah, now it's working. And if you explore this, so it's like there's a bunch of pretty nice stuff here that you can do like everything. You can even add your, of course, your custom domain or upgrade it or whatever, but there's like a free tier. And so this is the first part. The second part we would wanna do now right now is contentful whenever we wanna do something and contentful that it gets pushed here. So to do this, we need to add, create a webhook from here and add it there. And if you don't know what a webhook means, it's so out as is something that would trigger another thing like in a matcher, but a webhook would be, if you create a webhook from a website, this means that you will get the URL that if you call this URL, it will do something on the other website on the website that you need it. So in this case, we want contentful to head this API call or hit this URL and then AWS will know that. Yeah, something happened here, we should run this which is a redeployment. Yeah, we're sure. So yeah, so let's go back to contentful or sorry, let's first create the webhook. I think I need much more. Where can we create webhooks here? For general, monitoring, access control, bill settings. Yeah, bill settings. So we need to create a webhook here and we would call it content update for example. And yeah, it gives you like what to build when this happens. This is the predefined configurations of what happened or the predefined execution that what happened, when this API is called.
Seamless Content Deployment with AWS & Contentful
To deploy the website on AWS Amplify, sign into the AWS console and select AWS Amplify. Connect to the Git repository and click next, save, and deploy. The build process will clone the repository and provision the environment. The frontend assets will be generated, including HTML files for the category template and articles. To fix self-hosted images, modify the rewrites and redirects to include the webp format. Explore the deployed website and add a webhook in Contentful to trigger redeployment on AWS. Create the webhook in the bill settings and define the execution when the API is called.