Skip to content

Devchallenges - Legacy - Full-Stack Developer - Cat Wiki

Notifications You must be signed in to change notification settings

jdegand/devchallenges-cat-wiki

Repository files navigation

Cat Wiki

Solution for a challenge from Devchallenges.io.

Table of Contents

Overview

Homepage Mobile


Homepage Mobile 2


Mobile Suggestions


Homepage


Homepage Input Focus


Input Search Suggestions


Suggestions gone


Detail Page 1


Detail Page 2


Detail Page 1000px


Detail Page 1000px 2


Detail Mobile


Detail Mobile 2


See More Page 1


See More Page 2


Benefits Page


Built With

Features

This application/site was created as a submission to a DevChallenges challenge. The challenge was to build an application to complete the given user stories. Note: The previous design document may be incomplete, as you need to find an archived version of the challenge as all legacy challenges have had their documentation removed from DevChallenges.

  • I can search for cat breeds and select a breed of my choice
  • I can see the most popular searched cat breeds summary on the homepage
  • I can see the top 10 most searched cat breeds
  • I can see the breed details including description, temperament, origin, life span, adaptability, affection level, child-friendly, grooming, intelligence, health issues, social needs, stranger friendly
  • I can see more photo of the breed
  • On mobile, when I select the search option, a modal for breed search should pop up
  • I can go to an article about cats when I click read more on Why you should have a cat section
  • I can go to the top 10 cats by clicking see more in the dashboard

Thoughts

  • DevChallenges did not add a design for two pages: the breeds index page and the why you should have a cat page.
  • You can't search for multiple breeds at once on the API. You have to use a promise.all() / multiple fetches to get each breed needed, i.e. /breeds/search?q=beng.
  • You can get 4 random images with image search and the limit parameter, but it is random, and some pictures don't make sense for the design. Plus, image search gives you no idea of the breed etc.
  • Image component has a lot of quirks and things to be mindful of. Responsive image optimization is a nightmare. It shouldn't be this unclear to do things that are extremely easy to do in basic HTML code. Adding a srcSet to the Image component is not really covered. Having multiple images is not really necessary with the Image component. So do you use the largest image exclusively? Next does scale down. Can it scale up from a medium-sized image?
  • There have been many updates to Next Image since I first did this challenge. I need to investigate more to better optimize images in the app.
  • I used layout="responsive", and under tablet sizes, the background became too small when there was more space available. You have to set image sizes in the config for device sizes that are not default values.
  • You have to worry about duplicate pictures in the other images section.
  • Aegean has the same picture with different IDs, which shows up in the other images section.
  • You can use a ref to try and prevent the label from overlapping the text of the input on blur.
  • I fixed overlapping by using a valid pseudo-selector on the input in the css.
  • Using a layout page caused styling issues. The minimum height is 100 vh in globals.css, but it seems not to have been applied as the benefits page's footer was not at the bottom of the page.
  • There is a problem with the European Burmese detail page. The breed doesn't have a reference_image_id. The API request for the image fails and this prevents the page from showing any content. Since I am using fetch, the error handling is not as easy or as clean to implement.
  • Originally, the Read More and See More links were paragraph tags inside the Link element. I changed them to buttons so they can be tabbable. Similarly, I added buttons to breeds list page so they can easily be tabbed through as well.
  • However, this is problematic as having a button inside an <a> tag is illegal in HTML5. You need to add baseHref={true} to the <Link> tag so the links will be tabbable. See Github for more.
  • When I converted from Next 12 to Next 14, Image had the most breaking changes. I decided to stick with the legacy image implementation.
  • images.domains was deprecated. I replaced it with images.remotePatterns.
  • The cat API documentation has improved since I first tackled this challenge. I could look more into a voting system and the favoriting of breeds. Doing it may require logins or a local storage cookie to prevent a single user from voting excessively.
  • Next 14 supports Node 16 until early 2024 and then you will need Node 18.
  • I decided not to add TypeScript when converting to App Router.
  • I followed this guide to convert to App Router.
  • Without adding a head.js file, can you change the favicon? Yes. Next will look for files that start with icon, favicon, or apple-icon in the app folder.
  • When copying pages over to the app router, it is best to name them slightly different. This allows you to keep your original page, as naming conflicts will prevent the app from running.
  • You can't utilize useSearchParams with server-side data loading.
  • This means you have to add 'use client' and use a useEffect to load data with the searchTerm.
  • This is a lose-lose situation as useEffect is slower for data fetching, and you have to worry about memory leaks and possibly add a cleanup function. Adding abort controllers with multiple requests is more involved with less documentation available.
  • You need to add React Suspense when using useSearchParams. Next will throw an error before your state and page updates.
  • I incrementally added all pages to the app router. I deleted the pages/_app.js file and the remaining breed page did not have the correct styling and layout. It is important to keep your pages/_app.js file whenever you are using any page files.
  • I needed to use encodeURI on the breed names inside the Link hrefs. Spaces are not allowed inside a link's href.
  • Prior to the Next 14 conversion, I checked for duplicate pictures in the extra images grid. I have not done that here. Ultimately, even if you perform a filter to exclude duplicate file names, the API database has entries of the same photo with a different file name. I documented this issue in my Angular conversion of this project.
  • The breed detail page was deopted and used the client to fetch the data. This may expose the API key. I looked in the devtools and the x-api-key was undefined for the API requests. This error was caused by an incorrect placement of React Suspense. Suspense is needed when you add useSearchParams. I think the Suspense needs to wrap a component function and not just JSX.
  • I had the Suspense inside a main tag. Suspense probably needs to be the outermost element in its component. The fallback displays very briefly. Even on slow 3G, the loading text was barely there. It seems like you only see the Fallback when you run the build version of the app.
  • The breeds.module.css was preloaded, but it was not used by the breed page.
  • Link component preloads CSS modules and this causes a warning in the console. If there are many Link tags, the browser console will be flooded. This is very annoying. If you add prefetch={false} to the Link tag, the warning will go away. Performance implications? I didn't notice much of a difference.
  • App router seems to have a very loose CSS structure. You can colocate CSS anywhere. I am not really a fan of this and I preferred using a styles folder. In my conversion, I left the original styles folder and I still have it for now. I could move the component styles into the components folder or I could just add the files to the base app folder.
  • Link's default styling throws off my header's styling. I used the same html as my Angular conversion and just changed the a tags to Link tags and the CSS was off.
  • Header and Footer components have limited styling so I initially added those styles to global.css. I have since removed those styles and added a Footer module while adding the Header's styling inline.
  • Testing Next 14's App Router is uncharted territory. It is tough to decide on an approach that works. I think E2E testing is further along than unit testing.
  • Next testing documentation is not done.
  • MSW works with client side pages, but does not work with server rendered pages. See Github for more.

Continued Development

  • Investigate catapi changes
  • API error handling improvements
  • Typescript ?
  • Testing
  • Better dynamic page title implementation
  • Filter duplicate image entries from the Breed page
  • Suspense issues
  • Header styling issues on screens smaller than 425px & various other CSS issues

How To Use

To clone and run this application, you'll need Git and Node.js (v18+) (which comes with npm) installed on your computer. From your command line:

# Clone this repository
$ git clone https://github.com/jdegand/devchallenges-cat-wiki.git

# Install dependencies
$ npm install

# Before you run the app
# disable telemetry with `npx next telemetry disable` command

# Add .env.local with API_KEY from thecatapi

# Run the app and navigate to localhost:3000
$ npm run dev

Useful Resources

Releases

No releases published

Packages

No packages published