`HeroCallToAction` component
Introduction
Section titled βIntroductionβIn this guide, we will learn how to use and build custom components for your Epic News site.
The starter project that you have downloaded comes with several custom components that you can use to build your site.
We will start with these as a foundation, and then you can build your own custom components as you need them.
Pre-built Custom Components
Section titled βPre-built Custom ComponentsβThe Epic News starter project comes with several custom components that you can start to build your site with.
Letβs take a look at some of these.
Hero sections
Section titled βHero sectionsβA hero section is a large, prominent section at the top of a page that is used to grab the userβs attention.
Typically, there are two main styles of hero image:
-
The first is an image that is placed to one side of the page with a call to action section on the other:
-
The second is a full-width image that spans the width of the page, sometimes overlaid with custom content:
There are two main hero components in the Epic News starter project.
In this first guide, we will look at the HeroCallToAction
component.
1. The HeroCallToAction
component
Section titled β1. The HeroCallToAction componentβThe HeroCallToAction
component offers a quick way to display a hero section that places an image to one side of the page, and custom content of your own on the other.
-
Open
app/root.tsx
-
Add the following to the end of your
import
list:
6 collapsed lines
import { type LinksFunction } from '@remix-run/node'import { useLoaderData } from '@remix-run/react'import Document from '~/components/shared-layout/Document'import ThemeSwitch from '~/components/shared-layout/ThemeSwitch'import { useNonce } from '~/utils/nonce-provider.ts'import rootLinkElements from '~/utils/providers/rootLinkElements'import { loader } from './__root.server'import useTheme from './hooks/useTheme.tsx'import HeaderWithSearch from './components/organisms/HeaderWithSearch'import HeroCallToAction from './components/organisms/Hero/HeroCallToAction.tsx'
-
Next, slot this component just below the
h1
tag in the JSX being returned by theApp
component.Donβt worry about the red underline that appears under the
HeaderWithSearch
component for now - we will fix this in a moment:
16 collapsed lines
import { type LinksFunction } from '@remix-run/node'import { useLoaderData } from '@remix-run/react'import Document from '~/components/shared-layout/Document'import ThemeSwitch from '~/components/shared-layout/ThemeSwitch'import { useNonce } from '~/utils/nonce-provider.ts'import rootLinkElements from '~/utils/providers/rootLinkElements'import { loader } from './__root.server'import useTheme from './hooks/useTheme.tsx'import HeaderWithSearch from './components/organisms/HeaderWithSearch'import HeroCallToAction from './components/organisms/Hero/HeroCallToAction.tsx'
export const links: LinksFunction = () => { return rootLinkElements}export { headers, meta } from './__root.client.tsx'export { action, loader } from './__root.server.tsx'
export default function App() { const data = useLoaderData<typeof loader>() const nonce = useNonce() const theme = useTheme()
return ( <Document nonce={nonce} theme={theme}> <div className="flex h-screen flex-col justify-between"> <HeaderWithSearch />
<div className="flex-1"> <main className="grid h-full place-items-center"> <h1 className="text-mega">Welcome to Epic News!</h1> <div className="w-full py-16"> <HeroCallToAction /> </div> </main> </div>
<div className="container flex justify-between pb-5"> <ThemeSwitch userPreference={data.requestInfo.userPrefs.theme} /> </div> </div> </Document> )}
- You will notice that the
HeroCallToAction
component is underlined in red. Letβs find out why by hovering our mouse over it:
The error message is telling us that the component is expecting two props to be passed to it: image
and children
.
Letβs add these now.
- Delete the line shown in red, and add the section of JSX code shown in green below:
export default function App() { const data = useLoaderData<typeof loader>() const nonce = useNonce() const theme = useTheme()
return ( <Document nonce={nonce} theme={theme}> <div className="flex h-screen flex-col justify-between"> <HeaderWithSearch />
<div className="flex-1"> <main className="grid h-full place-items-center"> <h1 className="text-mega">Welcome to Epic News!</h1> <div className="w-full py-16"> <HeroCallToAction /> <HeroCallToAction image="https://www.helpguide.org/wp-content/uploads/2020/01/Social-Media-and-Mental-Health.webp"> <div className="flex flex-col gap-8 px-8"> <h2 className="text-h2">Welcome to Epic News</h2> <p className="text-lg"> Keep up to date with the latest tech news. </p> </div> </HeroCallToAction> </div> </main> </div>
<div className="container flex justify-between pb-5"> <ThemeSwitch userPreference={data.requestInfo.userPrefs.theme} /> </div> </div> </Document> )}
Save the changes to your file and head back to your browser.
You should now see the HeroCallToAction
component displayed correctly on your site:
1a. Optional HeroCallToAction
props
Section titled β1a. Optional HeroCallToAction propsβ-
Open the component file at
app/components/organisms/Hero/HeroCallToAction.tsx
(if you havenβt already). -
If you look inside the
HeroCallToAction
component code, you will see that it has aninterface
defined at the top of the file.This interface describes the props that the component expects to receive.
Letβs take a look:
app/components/organisms/Hero/HeroCallToAction.tsx interface HeroCallToActionProps {image: stringimageRight?: booleanhasBackgroundColour?: booleanchildren: React.ReactNode}This tells us that the component has two optional props as well as the mandatory ones weβve been using already.
Optional props are those that donβt have to be passed to the component when it is used, but can be if needed.
We can tell which props are optional by the
?
symbol after the prop name:app/components/organisms/Hero/HeroCallToAction.tsx interface HeroCallToActionProps {image: stringimageRight?: booleanhasBackgroundColour?: booleanchildren: React.ReactNode}The
imageRight
prop is a boolean that determines whether the image should be displayed on the right or left side of the component.The
hasBackgroundColour
prop is another boolean, but this one determines whether the component should have a background colour. -
Letβs try adding an
imageRight
prop to the component where we call it inapp/root.tsx
:
<HeroCallToAction image="https://www.helpguide.org/wp-content/uploads/2020/01/Social-Media-and-Mental-Health.webp" imageRight={true}> <div className="flex flex-col gap-8 px-8"> <h2 className="text-h2">Welcome to Epic News</h2> <p className="text-lg"> Keep up to date with the latest tech news. </p> </div></HeroCallToAction>
With this change saved, check your browser again:
Exploring the custom components in the Epic News starter project will help you understand how they work and how you can build your own.
Looking at the interface
expected by a component will help you understand what props you need to pass to it.
Summary
Section titled βSummaryβIn this step, we have:
- Used the
HeroCallToAction
component to display a hero section on our site. - Explored the
HeroCallToAction
componentβs props and how to pass them to the component. - Customised the
HeroCallToAction
component by adding our own custom content and styling.
Whatβs next?
Section titled βWhatβs next?βIn the next step, we will import and use another custom component - the ParallaxBackground
hero component.