Show article images (optional)
Introduction
Section titled βIntroductionβWe are currently only fetching the id
of each image from the database. To display the images on the page, we will need to generate a src
for each image using a utility function from the Epic Stack.
If you remember from a previous guide, we created a utility function called getArticleImgSrc
to generate a src
for each article image.
Configuring ArticleCard
Section titled βConfiguring ArticleCardβIf you have the getArticleImgSrc
function in place, we can now use it to display real article images on the page.
-
Open
app/routes/news.$category.tsx
.Add the line of code below to pass the
id
of the first article image to theArticleCard
component:app/routes/news.$category.tsx 24 collapsed linesimport { invariant } from '@epic-web/invariant'import { type LoaderFunctionArgs, json } from '@remix-run/node'import { useLoaderData } from '@remix-run/react'import ArticleCard from '#app/components/organisms/ArticleCard.tsx'import { prisma } from '~/utils/db.server.ts'import { toTitleCase } from '~/utils/stringUtils.ts'export async function loader({ params }: LoaderFunctionArgs) {const { category } = paramsinvariant(typeof category === 'string', 'Category not found')const categoryTitle = toTitleCase(category)const allArticles = await prisma.article.findMany({select: {id: true,title: true,category: { select: { name: true } },images: { select: { id: true } },},})return json({ categoryTitle, allArticles })}export default function NewsCategoryPage() {const { categoryTitle, allArticles } = useLoaderData<typeof loader>()return (<div className="container py-16"><h2 className="mb-8 text-h2">{categoryTitle}</h2><div className="grid grid-cols-2 gap-6 md:grid-cols-3 lg:grid-cols-5">{allArticles.map(article => (<ArticleCardkey={article.id}title={article.title}category={article.category?.name}imageId={article.images[0]?.id}/>))}</div></div>)} -
Open your
ArticleCard
component. -
Add the following import statements at the top of the
ArticleCard
component file to import thegetArticleImgSrc
function:app/components/organisms/ArticleCard.tsx import {MdOutlineBusinessCenter,MdOutlineTheaters,MdOutlineDesktopMac,MdOutlineNewspaper,} from 'react-icons/md'import { getArticleImgSrc } from '~/utils/misc.tsx'import siteLogo from '~/assets/svg/site-logo.svg'26 collapsed linesinterface ArticleCardProps {title: stringcategory?: string}export default function ArticleCard({title,category = 'General news',}: ArticleCardProps) {const categoryIcons: { [key: string]: JSX.Element } = {Business: <MdOutlineBusinessCenter size={20} className="text-red-300" />,Entertainment: <MdOutlineTheaters size={20} className="text-red-300" />,Technology: <MdOutlineDesktopMac size={20} className="text-red-300" />,'General news': <MdOutlineNewspaper size={20} className="text-red-300" />,}return (<div className="flex h-64 cursor-pointer flex-col justify-between rounded bg-red-900 p-4 transition-all duration-500 hover:scale-110"><h3 className="line-clamp-3 text-xl font-bold">{title}</h3><div className="flex items-center gap-2">{categoryIcons[category]}<p className="text-sm text-red-300">{category}</p></div></div>)} -
With this in place, letβs now modify the logic inside our
ArticleCard
component to display the article image above the title:app/routes/news.$category.tsx 8 collapsed linesimport {MdOutlineBusinessCenter,MdOutlineTheaters,MdOutlineDesktopMac,MdOutlineNewspaper,} from 'react-icons/md'import siteLogo from '~/assets/svg/site-logo.svg'import { getArticleImgSrc } from '~/utils/misc.tsx'interface ArticleCardProps {title: stringcategory?: stringimageId?: string}export default function ArticleCard({title,category = 'General news',imageId,}: ArticleCardProps) {const imageSrc = imageId ? getArticleImgSrc(imageId) : siteLogo6 collapsed linesconst categoryIcons: { [key: string]: JSX.Element } = {Business: <MdOutlineBusinessCenter size={20} className="text-red-300" />,Entertainment: <MdOutlineTheaters size={20} className="text-red-300" />,Technology: <MdOutlineDesktopMac size={20} className="text-red-300" />,'General news': <MdOutlineNewspaper size={20} className="text-red-300" />,}return (<div><div><imgsrc={imageSrc}alt={title}/></div><div className="flex h-64 cursor-pointer flex-col justify-between rounded bg-red-900 p-4 transition-all duration-500 hover:scale-110"><h3 className="line-clamp-3 text-xl font-bold">{title}</h3><div className="flex items-center gap-2">{categoryIcons[category]}<p className="text-sm text-red-300">{category}</p></div></div></div>)} -
Check the browser. You should now see the article images displayed above the title on each article card, although they are not perfect yet:
Summary
Section titled βSummaryβIn this guide, we learned how to:
- Pass the
id
of each article image to theArticleCard
component - Use the
getArticleImgSrc
function to generate thesrc
for each article image - Display the article images above the title on each article card
- Style the article images to make them a consistent size and shape
In the next guide, we will learn how to filter articles by the correct category.