Personal Project
Anime Volt
Anime Volt is a web application designed to showcase trending anime movies by fetching data from an external API. The project highlights server actions in Next.js and features seamless infinite scrolling for a smooth user experience. It focused on exploring efficient data fetching and dynamic rendering techniques.
About This Project
Overview
Anime Volt is a dynamic web application designed to present trending anime movies by leveraging data from the Shikimori API. The project showcases advanced features of Next.js, focusing on efficient server actions, smooth infinite scrolling, and seamless user experiences enhanced by Framer Motion animations.
Key Features
- Server Actions with Next.js: The project utilizes server actions, a feature introduced in Next.js 13.4 and improved in version 14. This approach allows for writing asynchronous functions that run server-side, avoiding the need for separate API routes. By integrating server actions directly into components, the application enhances performance, maintains a clean architecture, and reduces boilerplate code.
- Data Fetching from the Shikimori API: The app fetches anime data from the Shikimori API, which provides a paginated list of popular anime based on user preferences. The API endpoint (https://shikimori.one/api/animes) is configured to fetch up to 8 popular anime titles per request, ensuring quick data retrieval and an up-to-date browsing experience for users.
- Infinite Scrolling for a Seamless User Experience: Instead of traditional pagination, the app implements an infinite scrolling feature using the react-intersection-observer library. This allows new anime content to load automatically as the user scrolls, providing a continuous browsing experience without interruptions. The approach enhances user engagement and creates a fluid interface.
- Smooth Animations with Framer Motion: To deliver an engaging visual experience, Framer Motion is used for animating the appearance of new anime cards. Each card fades in with a staggered delay, creating a polished and interactive feel. This use of animations contributes to a modern, responsive UI that captures user attention.
Technology Stack
- Frontend: Next.js, TypeScript, React
- Backend: Next.js Server Actions
- APIs: Shikimori API for anime data
- Libraries: react-intersection-observer for infinite scrolling, Framer Motion for animations
Anime Volt provides a robust and efficient way to explore trending anime movies, offering users an enjoyable and visually appealing experience while demonstrating advanced capabilities of modern web technologies.
Server Actions
Server Actions are a feature in Next.js that allows developers to write asynchronous functions that run directly on the server. This approach eliminates creating separate API routes for specific actions like fetching external data, performing business logic, or handling mutations. Instead, these actions can be seamlessly integrated into Next.js components, reducing boilerplate and improving developer experience.
Server Actions were introduced in Next.js version 13.4 as an experimental feature and have seen further improvements in version 14
Here's an example of the server action from this project:
"use server"
import AnimeCard, { AnimeProp } from "@/components/AnimeCard";
export const fetchAnime = async (page: number) => {
const response = await fetch( `https://shikimori.one/api/animes?page=${page}&limit=8&order=popularity` );
const data = await response.json();
return data.map((item: AnimeProp, index: number) => (
<AnimeCard key={item.id} anime={item} index={index} />
));
};
This code defines an asynchronous function that fetches anime data from an external API and renders it using a React component. It uses the "use server" directive, indicating that the function is a server action, meaning it executes on the server rather than the client. This approach helps enhance security by keeping API requests server-side and reduces the load on the client.
The function first requests a list of popular anime from the Shikimori API, using a specific page number for pagination. The fetched data is then parsed as JSON. Next, the data is transformed into a series of React components, each representing an anime item. The function returns these components directly, using a custom AnimeCard component that displays details of each anime item. Each card is identified by a unique key to help React manage the component list efficiently.
Overall, this code combines data fetching, server-side execution, and component rendering into a streamlined process, leveraging Next.js server actions to ensure better performance and a secure API call. The use of TypeScript adds type safety, defining the structure of the anime data using a custom type (AnimeProp). This setup is particularly useful for rendering lists of content dynamically while keeping the process efficient and secure.
Fetching From The API
Fetching the data from Shikimori.one
The Shikimori API endpoint (https://shikimori.one/api/animes?page=${page}&limit=8&order=popularity
) is designed to fetch a list of anime based on popularity. It provides a paginated response, allowing users to retrieve a limited number of anime entries per request. By specifying the page parameter, you can navigate through different pages of the dataset. The limit parameter controls how many anime items are returned in each response (in this case, 8 items per request). Finally, the order=popularity filter sorts the results by their popularity, ensuring that the most popular titles are shown first.
This API is particularly useful for creating features like anime recommendation lists, trending titles, or for building applications where users want to explore popular anime without requiring extensive filtering or search capabilities. It offers a streamlined way to access widely liked anime content and integrates well with front-end components, providing a user-friendly experience for anime enthusiasts.
Infinite Scrolling
Infinite scrolling is a user interface pattern where content is dynamically loaded as the user scrolls down the page, eliminating the need for pagination. Instead of clicking "Next" or "Load More," new content is fetched and displayed automatically, creating a seamless and continuous browsing experience. This technique is commonly used in social media feeds, e-commerce sites, and search results to keep users engaged without interruptions.
Here is how I was able to implament infinite scrolling within this project
let page = 2;
export type AnimeCard = JSX.Element;
function LoadMore() {
const { ref, inView } = useInView();
const [data, setData] = useState<AnimeCard[]>([]);
useEffect(() => {
if (inView) {
fetchAnime(page).then((res) => {
setData([...data, ...res]);
page++;
});
}
}, [inView, data]);
This code snippet demonstrates a simple "infinite scrolling" or "load more" feature in a React component. Here’s an overview of what it does:
- State Management for Anime Data: It initializes a state variable called data to hold an array of anime cards. The AnimeCard type defines each item as a JSX element.
- Intersection Observer Hook: The useInView hook from the react-intersection-observer library is used to detect when a specific element (referred to by ref) enters the viewport. This allows us to determine when the user has scrolled to the bottom of the content.
- Fetching Additional Anime Data: Within a useEffect hook, the code checks if the inView variable is true, indicating that the element is in the user's viewport. When this condition is met, it triggers the fetchAnime function, which fetches the next page of anime data from an API.
- Updating the Data and Pagination: Once the new data is fetched, it is added to the existing data array using the setData function. The page counter is then incremented to load the next set of anime items on subsequent scrolls.
In essence, this code component enhances the user experience by continuously loading more anime items as the user scrolls down the page, creating a seamless browsing experience without the need for manual interaction (e.g., clicking a "Load More" button).
Framer Motion
Framer Motion is a popular React library for creating smooth, interactive animations with ease. It offers a declarative API for animating elements, allowing developers to add animations directly to their JSX. The library handles complex transitions, gestures, and layout animations without requiring manual calculations. Framer Motion also supports spring-based physics animations, drag-and-drop interactions, and viewport-based animations, making it ideal for creating engaging, responsive user interfaces in modern web applications.
This library was used to create a smooth loading transition effect. As new anime cards are loaded, each card fades in from an opacity of 0 to 1. The transition for each card includes a staggered delay, calculated as index * 0.25
, to enhance the visual experience.
Conclusion
Anime Volt demonstrates the effective use of modern web technologies like Next.js Server Actions, TypeScript, and seamless infinite scrolling to create a responsive and engaging anime discovery experience. By leveraging data from the Shikimori API and enhancing the interface with smooth animations via Framer Motion, the project delivers a polished, user-friendly platform for exploring trending anime titles. This project showcases the integration of efficient server-side rendering, interactive UI patterns, and dynamic data fetching, making it a comprehensive example of building scalable, high-performance web applications.