Create a React Studio Ghibli Info app

Studio Ghibli has created some of the most awe inspiring and charming films that I have ever seen, so what's better than combining two of my favourite things, React and Studio Ghibli.

In this tutorial, we will be exploring the React framework and creating a React app that will make use of components and an API for movie info.

Setup & Getting Started

Before we can create our React app, we will need the following installed:

  • Node.js
  • NPM
  • Visual Studio Code

Node.js can be downloaded from the Node JS website and NPM will be included by default in the Node installation.

Now that everything is installed and ready to go, let's get started.

We'll need to create our React app first which we will be doing using Vite and NPM, other options like Create-react-app are bundled with webpack by default and my preference with React apps tends to stick with Vite as it's quick and easy to use.

In your command prompt, go to the desired project folder using cd directory-name and run the following command:

Vite bootstrapping command

This command specifies what template we want to use (react) and what our project name will be (ghibli-app). Once Vite has completed scaffolding the project, let's enter the code with the following:

cd ghibli-app
code .

This will place us into our React app project directory then code . will open the project within Visual Studio Code.

Let's Get Our Data

There is a vital element of every application that we can't forget, data. Every website relies on some form of data.

For our project, we're going to be using the Studio Ghibli API. All of the documentation for the API is available from the link.

We will also need a way to present our data and that's where this React project will come in handy, let's get started:

To start, we want to create a file structure on our newly created project like this:

src
┣ components
┃ ┗ Cards
┃ ┃ ┣ Cards.component.jsx
┃ ┃ ┗ Cards.module.css
┣ hooks
┃ ┗ useFetch.js
App.css
App.jsx
┣ favicon.svg
┗ main.jsx

As you can see in the image above, I have already created some of the files we will need today. Go ahead and create any missing files (some already exist when bootstrapping our app).

Let's Code!

So now you're already to dive into the code, we are going to start with the useFetch hook, this will be the way we fetch from the Ghibli API. This is how our useFetch hook should look:

import { useState, useEffect } from 'react';
const useFetch = (url, options) => {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const res = await fetch(url, options);
const json = await res.json();
setData(json);
} catch (error) {
setError(error);
}
};
fetchData();
}, []);
return { data, error };
};
export default useFetch;

Let's break down what we've just created, we created a function called useFetch that takes in a url and an object called options as parameters, we then create our state variables data and error using the React useState hook and make use of the useEffect hook to create our fetchData method.

Within the useEffect in our fetchData method, we start off with creating a variable called res that will contain the response from the fetch url that we pass a url and some options and then create a variable called json that will hold our response data in a json format.

We've encapsulated the method within a try catch to catch any exceptions that may occur when fetching data from the API.

Displaying the Data!

Now that you've created a hook to fetch the data from the Ghibli API, we'll need to add a way to display that data. Let's utilise the Cards.component.jsx file that you have created to display the data with JavaScript.

import { useEffect } from 'react';
import useFetch from '../../hooks/useFetch';
import styles from './Cards.module.css';
const url = `https://ghibliapi.herokuapp.com/films`;
function Cards() {
const { data, error } = useFetch(url);
useEffect(() => {
if (error) {
alert(error.message);
}
})
return !data ? (
<div>
<p>No data.</p>
</div>
) : (
<div className={styles.cards}>
{data.map((film) => (
<div className={styles.card} key={film.id}>
<div className={styles['title-bg']}>
<h1>{film.title}</h1>
<h1>{film.original_title}</h1>
</div>
<p>Director: {film.director}</p>
<p>Initial Release: {film.release_date}</p>
<p>Description:</p>
<p>{film.description}</p>
</div>
))}
</div>
)
}
export default Cards;

Before we declare the functional component 'Cards' let's set the URL for the Films endpoint on the Ghibli API, this will be where get all of film info.

After declaring Cards we can finally call our fancy new hook 'useFetch', let's declare the data and error variables and pass the url to the useFetch hook. The error variable will allow us to handle any issues when fetching the data.

To handle any errors let's create a useEffect that will show an alert in the browser if there is an error. Now that we have our data and error the only thing left is to create some jsx to display the data.

What you can see in the return statement is called JSX which is used by React to write HTML directly within JavaScript code.

To begin we will create the return and add a ternary operator, this will evaluate if a value is truthy or falsy and execute either the left (truthy) or right (falsy) expression, let's check if data is false by adding the ! operator and return a div with an error message and after the colon we can create our grid.

We're going to iterate through the data array for each film and display a div that will resemble a card.

The styles for this should be placed in Cards.module.scss and should look like this:

.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin: 4rem 5vw;
padding: 0;
list-style-type: none;
}
.card {
position: relative;
display: block;
height: 100%;
border-radius: 1rem;
overflow: hidden;
text-decoration: none;
background-color: white;
box-shadow: 0 8px 16px -4px rgba(0,0,0,0.65);
}
.card:hover {
transform: translateY(-8px);
transition-duration: 0.3s;
transition-property: transform;
transition-timing-function: ease-out;
cursor: pointer;
}
.cards h1 {
color: white;
font-size: 1rem;
}
.cards p {
text-align: left;
font-size: 0.8em;
font-weight: bold;
padding: 0 12px;
}
.cards p:last-child {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 8;
-webkit-box-orient: vertical;
padding-bottom: 0.2em;
}
.title-bg {
overflow: hidden;
}
.card:nth-child(1n+0) .title-bg {
background-color: #f5bfd2;
}
.card:nth-child(2n+0) .title-bg {
background-color: #e5db9c;
}
.card:nth-child(3n+0) .title-bg {
background-color: #d0bcac;
}
.card:nth-child(4n+0) .title-bg {
background-color: #beb4c5;
}
.card:nth-child(5n+0) .title-bg {
background-color: #e6a57e;
}
a {
text-decoration: none;
color: inherit;
}

If you tried to run the app at this point with yarn dev you will not see all of the work we did on the Cards component, that's because we need to add it to our App.jsx component.

import Cards from './components/Cards/Cards.component';
import './App.css'
function App() {
return (
<div>
<Cards />
</div>
)
}
export default App

The styling for this component should be placed in App.css and should look like this:

* {
box-sizing: border-box;
}
html {
display: flex;
}
body {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
text-align: center;
color: black;
font-family: 'Noto Sans', sans-serif;
background-color: #faf9f9;
}

Try running yarn dev now and you should be able to view all of the fantastic movies that Studio Ghibli have created over the years.

Troubleshooting

If you are still having issues running the application, you might be missing a call to the App component within main.jsx, it should look like this:

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
)

Thank you for reading through and hopefully you've just created your very own Studio Ghibli movie app in React ✨

Check out the tutorial code here!