Check out a free preview of the full Intermediate Gatsby with Gatsby Themes course:
The "Client Routes" Lesson is part of the full, Intermediate Gatsby with Gatsby Themes course featured in this preview video. Here's what you'd learn in this lesson:

Jason live codes a form for the search page started earlier on this course, a search query, routes and redirects using netlify.

Get Unlimited Access Now

Transcript from the "Client Routes" Lesson

[00:00:00]
>> Jason Lengstorf: All right, so our first piece here is going to be to create a form, so that we can track what people are searching for. They need to be able to actually input a search term and then we wanna take that search term on submitting the form, rewrite the URL with it.

[00:00:15] So that means that we need to make the search term URL-friendly. So we're gonna do a little bit of string munging to make that work and then we'll also get into programmatic navigation with Gatsby using the navigate helper function. So first, we're just gonna hop into our source folder and let's create a components folder and inside of that, we'll create a form.

[00:00:41] And this is gonna be our search form. So I'm gonna import React from React. And then we're gonna set up our form, so const form, and that will return something, that will export default.
>> Jason Lengstorf: Okay, so inside of our form, we want to set up just a form.

[00:01:06] And then, onSubmit, we need to do something. So let's create a function called handleSubmit.
>> Jason Lengstorf: And that's gonna do something, and then inside of our form, we're going to set up a label. And inside of the label we'll say search by name. And then we'll add an input of the type text.

[00:01:37] We will give it a name of name. And we'll set a value. And because we want to control the value, we want React to manage it. We don't want it to be kind of user-land managed. We're going to use the use state hook. So let's set up use state, and we'll say value.

[00:02:01] set value. And that's going to be the result of use state, and we'll just start it out empty. So our value here is going to be value. And then on change, we're going to handle input, which will be another helper function.
>> Jason Lengstorf: And then below, outside of our label, we're going to add a button.

[00:02:27] That button is gonna be of the type Submit. And it'll just say search. So, that is most of what we need. But now we need to make this, we need to handle input. So we can set up const handle input, and that's also gonna be a function.
>> Jason Lengstorf: So for handling the input, what we really wanna do is just get the current value and drop it in.

[00:02:56] So we can just get the event and then we're gonna set the value to event target value. And that will allow us to type in the field, and that'll update the state whenever we type. It's a pretty standard way of controlling inputs in React. If you've done this using class components, the useState hook is such a breath of fresh air in terms of how simple it makes it to control inputs.

[00:03:27] We're not writing out special class methods and then binding this to them and doing all these things that are like, you know, they're easy once you've memorized how they work but it's not easy. useState is a little bit funky to look at because when you look at hooks they've got these kind of array destructuring set up, and they kind of feel like magic a little bit.

[00:03:50] But once the the model kind of sets in, it really makes things straightforward and declarative, which is really, really wonderful to work with. In our handle, submit, what we want to do, is again, we're going to get an event. But in this case, we wanna prevent the form from going anywhere.

[00:04:10] We don't wanna like navigate to another page or refresh the page or any of the things that forms will typically do by default. So we're gonna do event.preventDefault, and that will prevent the form from, you know, blowing away our React app and taking us to, or like refreshing the page or anything.

[00:04:27] Underneath that, we need to turn the search string into a URL-friendly query. And then, we need to actually,
>> Jason Lengstorf: Change the URL to match our search results.
>> Jason Lengstorf: So, to turn this into a search-friendly query, we're gonna take the value up here, which could be anything. So what I'll actually do is, let's just get this on the screen, so we can see it.

[00:05:03] And then we'll start playing with how to handle the form. So let's get this. We're going to use that auto-import because that's neat. And then up here, that does what we want. Don't need that link actually. So let's get that out of there. And so now I've got a form.

[00:05:23] So let's start this up. I'm going to do netlify dev.
>> Jason Lengstorf: Okay, success, all right, and so now we've got a form, and we can type into it and it's doing what we expect. So if I move the console down here, so we can see it and then make it much bigger so we can read it, I can set this by default to console log value.

[00:06:04] So let's just take a field and search it, and it's gonna log something. Okay, good. So our form does submit. It handles the submit properly, it's not refreshing the page or anything. So the next thing that we want to do is what if somebody types in like Rick & Morty, something like that, that would break any URL, we can't just like link to that.

[00:06:32] It's also not particularly useful in the context of the lookup that we're doing. So because we know that our API's a text-based search, we don't need any special characters, so that drastically simplifies our job here. So the first thing that I want to do is, I'm just gonna go ahead and let's start by creating a new variable, which is gonna initially be the value, but then I'm gonna do a couple of transformations.

[00:06:59] I'm gonna change it to lowercase, I'm gonna trim any white space from the beginning and end. Then I'm gonna get into regular expression replacement. So we'll use a regex. And I'm going to create a set and say anything that is not a word character or a space,
>> Jason Lengstorf: And we're gonna go global with that, it's going to be replaced with nothing.

[00:07:24] So we're basically going through and stripping out any special characters, any non-space white space, all in. And so that's the letters A through Z and the number zero through nine. That's what the slash lowercase w allows. And the space character is just the space character. So not new lines, not tabs, nothing like that.

[00:07:47] So we're being pretty restrictive about what we're allowing. And then, because I wanna pass this in the URL and I don't want a bunch of ugly, like, percent 20s in there, I'm going to also replace any space character. And we will do one or more, just in case somebody says, like, Rick 15 spaces and then Morty, we don't like 15 hyphens, that's silly.

[00:08:09] So we're going to do one or more space characters. And again, we'll go global with that, and we'll replace it with a hyphen. So now I have this query. So let's console log it.
>> Jason Lengstorf: Okay, so upon doing that, what I should get is for an average query, like if I just type someone's name, nothing really changes, but if I start adding a bunch of nonsense in here,

[00:08:40]
>> Jason Lengstorf: It strips it to just the actual letter characters, and does so in a way that would work in a URL. So that's kind of what we're after, right? Is we want something that we can put in a URL and make it linkable, and we'll deal with reversing this in the results session.

[00:08:55] So, now that we know these are there, and it's doing what we want, we can use this query to rewrite our history. And to do that, we're going to use the navigate helper from Gatsby. So we're gonna import navigate from Gatsby, and inside of our handler, we're just going to navigate.

[00:09:29]
>> Jason Lengstorf: To search, and we'll use the query. And then, we're also going to pass that down. So we'll put it in the state as query.
>> Jason Lengstorf: So this means that we can pull the state that we've created right out of the query without having to parse the url or anything, when it's a local click.

[00:09:55] We'll still have to parse the URL when someone sends a link. But we can skip some work in the case that somebody's doing it locally, which will be, really, the most common use case. So upon doing this, what should happen is whenever we search, so I'll say, let's say, Morty, our URL just changed, and now it says slash Morty.

[00:10:18] And if I put a bunch of junk in here and then say Rick, it gets edited to Morty dash Rick. Cool. Okay, that's doing what we want. So let's save our work. And then we'll get that results page working.