Our First Page
Let's give our users something to look at besides the (awesome) Redwood welcome page (thanks @alicelovescake!). We'll use the redwood
command line tool to create a page for us:
yarn redwood generate page home /
The command above does four things:
- Creates
web/src/pages/HomePage/HomePage.tsx
. Redwood takes the name you specified as the first argument afterpage
and PascalCases it, then appends "Page" to construct your new page component. So "home" becomes "HomePage". - Creates a test file to go along with this new page component at
web/src/pages/HomePage/HomePage.test.tsx
with a single, passing test. You do write tests for your components, don't you?? - Creates a Storybook file for this component at
web/src/pages/HomePage/HomePage.stories.tsx
. Storybook is a wonderful tool for efficiently developing and organizing UI components. (If you want to take a peek ahead, we learn about Storybook in chapter 5 of the tutorial). - Adds a
<Route>
inweb/src/Routes.tsx
that maps the path/
to the new HomePage page.
If you look in Routes you'll notice that we're referencing a component, HomePage
, that isn't imported anywhere. Redwood automatically imports all pages in the Routes file since we're going to need to reference them all anyway. It saves a potentially huge import
declaration from cluttering up the routes file.
In case you didn't notice, this page is already live (your browser automatically reloaded):
It's not pretty, but it's a start! Open the page in your editor, change some text and save. Your browser should reload with your new text.
Routing
Open up web/src/Routes.tsx
and take a look at the route that was created:
- JavaScript
- TypeScript
import { Router, Route } from '@redwoodjs/router'
const Routes = () => {
return (
<Router>
<Route path="/" page={HomePage} name="home" />
<Route notfound page={NotFoundPage} />
</Router>
)
}
export default Routes
import { Router, Route } from '@redwoodjs/router'
const Routes = () => {
return (
<Router>
<Route path="/" page={HomePage} name="home" />
<Route notfound page={NotFoundPage} />
</Router>
)
}
export default Routes
As long as you have a route with path /
, you'll never see the initial Redwood splash screen again.
When no route can be found that matches the requested URL, Redwood will render the NotFoundPage
.
Try changing the route to something like:
- JavaScript
- TypeScript
<Route path="/hello" page={HomePage} name="home" />
<Route path="/hello" page={HomePage} name="home" />
The splash screen is available again at http://localhost:8910/, giving you a list of all the available URLs in your app.
Go to /hello
and you should see the homepage again.
Change the route path back to /
before continuing!
Simple Styles
Previous versions of this tutorial had you build everything without any styling, so we could really focus on the code, but let's face it: an unstyled site is pretty ugly. Let's add a really simple stylesheet that will just make things a little easier on the eyes as we build out the site. Paste the following into web/src/index.css
:
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica,
Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
}
ul {
list-style-type: none;
margin: 1rem 0;
padding: 0;
}
li {
display: inline-block;
margin: 0 1rem 0 0;
}
h1 > a {
text-decoration: none;
color: black;
}
button,
input,
label,
textarea {
display: block;
outline: none;
}
label {
margin-top: 1rem;
}
.error {
color: red;
}
input.error,
textarea.error {
border: 1px solid red;
}
.form-error {
color: red;
background-color: lavenderblush;
padding: 1rem;
display: inline-block;
}
.form-error ul {
list-style-type: disc;
margin: 1rem;
padding: 1rem;
}
.form-error li {
display: list-item;
}
.flex-between {
display: flex;
justify-content: space-between;
}
.flex-between button {
display: inline;
}
These styles will switch to whatever your OS's system font is, put a little margin between things, and just generally clean things up. Feel free to tweak it to your liking (or ignore these styles completely and stick with the browser default) but keep in mind that the following screenshots are made against this base stylesheet so your experience may vary.
Looking better already!