Auto Image Slider - React, Vite, JavaScript, Custom CSS, React Slick, Slick Carousel Fundamental Project 7
A learning-focused React application that demonstrates two ways to build an image slider: a custom carousel from scratch using React hooks, and a library-based carousel using React Slick. It is ideal for understanding state management, effects, event handling, and third-party library integration in React. You can try the live demo, clone the repo to run it locally, or reuse the components in your own projects.
Live Demo: https://auto-image-slider.vercel.app/
- Project Structure
- Technologies Used
- Installation & How to Run
- Environment Variables (.env)
- Project Walkthrough & Features
- Component Overview
- Data Structure
- How It Works โ Functionality & Code
- Reusing Components in Other Projects
- API, Backend & Routes
- Learning Points & Keywords
- References & Links
- Conclusion
- License
07-slider/
โโโ index.html # HTML entry; SEO meta and root div
โโโ package.json # Dependencies and scripts (dev, build, preview, lint)
โโโ vite.config.js # Vite configuration and React plugin
โโโ eslint.config.js # ESLint flat config for React/JSX
โโโ public/
โ โโโ vite.svg # Favicon and default OG image
โโโ src/
โโโ main.jsx # React app mount and global CSS import
โโโ App.jsx # Root component; renders Carousel (or SlickCarousel)
โโโ Carousel.jsx # Custom carousel (useState, useEffect, useCallback)
โโโ SlickCarousel.jsx # Carousel using react-slick
โโโ data.js # Slide data: shortList, list, longList
โโโ index.css # Global styles and carousel/slick styles- index.html: Entry HTML; contains meta tags for SEO and a single
<div id="root">for the React app. - main.jsx: Renders the app with
ReactDOM.createRootand imports globalindex.css. - App.jsx: Decides which slider is shown (currently the custom
Carousel;SlickCarouselcan be enabled by uncommenting). - Carousel.jsx: Custom slider with prev/next buttons and auto-advance using React state and effects.
- SlickCarousel.jsx: Same data displayed via the
react-slicklibrary with configurable options. - data.js: Exports
shortList,list, andlongList(arrays of slide objects) for use in either carousel. - index.css: Resets, CSS variables, layout, and styles for both carousels.
| Technology | Purpose |
|---|---|
| React 18 | UI components and state management |
| Vite 4 | Dev server, HMR, and production build |
| JavaScript (ES6+) | No TypeScript; modules, hooks, and modern syntax |
| react-slick | Library-based carousel with dots, arrows, autoplay |
| slick-carousel | Default CSS for react-slick |
| react-icons | Icons (e.g. FaQuoteRight, FiChevronLeft, FiChevronRight) |
| ESLint | Linting for React and React Hooks (flat config) |
There is no backend or database. All slide content is defined in src/data.js. The app is a single-page front-end only.
Prerequisites: Node.js (e.g. 18+) and npm (or yarn/pnpm).
-
Clone the repository
git clone https://github.com/arnobt78/Slider--React-Fundamental-Project-7.git cd Slider--React-Fundamental-Project-7 -
Install dependencies
npm install
-
Run the development server
npm run dev
Then open the URL shown in the terminal (typically http://localhost:5173).
-
Other scripts
npm run buildโ Production build (output indist/).npm run previewโ Serve the production build locally.npm run lintโ Run ESLint on the project.
No environment variables are required to run or build the project.
This project does not use any environment variables. All configuration is in code (e.g. data.js, component state, and react-slick settings). There is no API base URL, no keys, and no server-side config.
If you later add features that need env vars (e.g. an API or analytics ID), you can use Viteโs env support:
-
Create a
.envfile in the project root (optional; this file is in.gitignore):VITE_API_URL=https://api.example.com VITE_ANALYTICS_ID=your-id
-
Naming: Only variables prefixed with
VITE_are exposed to the client. Use them in code asimport.meta.env.VITE_API_URL, etc. -
Example: For an optional API base URL you could add in
.env:VITE_APP_TITLE=Slide Image Display
And in code:
const title = import.meta.env.VITE_APP_TITLE || 'Slider'; -
.env.example(optional): You can add a.env.examplewith placeholder keys and document it in the README so others know which vars are optional for extended features. The current app runs without any.envfile.
- Data: Uses
longListfromdata.js(array of objects withid,image,name,title,quote). - State:
useStatefor the list and for the current slide index (currentPerson). - Navigation: Previous/Next buttons call
prevSlide/nextSlide, which update the index with wraparound (modulo). - Auto-advance:
useEffectruns asetIntervalevery 5 seconds to callnextSlide; cleanup clears the interval.nextSlideis memoized withuseCallbackso the effect dependency is stable. - Layout: Each slide is absolutely positioned; the active slide is shown via
transform: translateX(...),opacity, andvisibilitybased on index. - Accessibility: Buttons are focusable and usable with keyboard.
- Data: Uses
listfromdata.js(fewer items; you can switch toshortListorlongListif desired). - Configuration:
react-slickis configured withdots,infinite,autoplay,pauseOnHover,slidesToShow: 2, etc. All options are in thesettingsobject. - Rendering:
<Slider {...settings}>wraps a.map()over the data; each item is an<article>with image, name, title, quote, and an icon. - Styling:
slick-carouselCSS is imported; project-specific overrides (e.g. arrow color) are inindex.cssunder the slick section.
In App.jsx, the custom carousel is shown by default. To use the Slick carousel instead, comment out <Carousel /> and uncomment <SlickCarousel />. You can also render both in different sections or tabs if you extend the app.
| Component | File | Role |
|---|---|---|
| App | App.jsx |
Root; renders one of the carousels (or both if you change the JSX). |
| Carousel | Carousel.jsx |
Custom slider: state, prev/next, auto-advance, slide list from longList. |
| SlickCarousel | SlickCarousel.jsx |
react-slick slider: list data and shared styling with Carousel. |
There are no routes (no React Router). The app is a single page that mounts App into #root.
Slide items are plain objects. All lists in data.js use the same shape:
{
id: number, // Unique key for React
image: string, // Image URL (e.g. from course-api or your CDN)
name: string, // Person or item name
title: string, // Subtitle or role
quote: string // Short text (e.g. testimonial)
}- shortList: 1 item (for quick tests).
- list: 4 items (used by
SlickCarousel.jsx). - longList: 8 items (used by
Carousel.jsx).
You can add more fields (e.g. link, avatar) and use them in the same components as long as you keep id and the fields the components expect (image, name, title, quote).
const [people] = useState(longList);
const [currentPerson, setCurrentPerson] = useState(0);
const nextSlide = useCallback(() => {
setCurrentPerson((oldPerson) => (oldPerson + 1) % people.length);
}, [people.length]);
const prevSlide = () => {
setCurrentPerson(
(oldPerson) => (oldPerson - 1 + people.length) % people.length,
);
};- Index is updated with wraparound so the slider loops.
nextSlideis wrapped inuseCallbackso it can be safely used insideuseEffectfor the timer.
useEffect(() => {
const sliderId = setInterval(() => nextSlide(), 5000);
return () => clearInterval(sliderId);
}, [nextSlide]);- Every 5 seconds the next slide is shown. The cleanup function prevents multiple intervals if the component re-runs.
Each slide is positioned with inline styles; only the active one is fully visible:
{
people.map((person, personIndex) => (
<article
key={person.id}
className="slide"
style={{
transform: `translateX(${100 * (personIndex - currentPerson)}%)`,
opacity: personIndex === currentPerson ? 1 : 0,
visibility: personIndex === currentPerson ? "visible" : "hidden",
}}
>
<img src={person.image} alt={person.name} className="person-img" />
<h5 className="name">{person.name}</h5>
<p className="title">{person.title}</p>
<p className="text">{person.quote}</p>
<FaQuoteRight className="icon" />
</article>
));
}const settings = {
dots: true,
infinite: true,
speed: 500,
slidesToShow: 2,
slidesToScroll: 1,
autoplay: true,
autoplaySpeed: 1000,
pauseOnHover: true,
};
return (
<section className="slick-container">
<Slider {...settings}>
{list.map((person) => (
<article key={person.id}>
{/* same structure: image, name, title, quote, icon */}
</article>
))}
</Slider>
</section>
);You can change slidesToShow, autoplaySpeed, or add options like fade: true as needed.
-
Copy components and data
- Copy
Carousel.jsx,SlickCarousel.jsx, anddata.js(or your own data file). - Ensure
react-slickandslick-carouselare installed if you useSlickCarousel. - Install
react-iconsif you keep the quote/chevron icons.
- Copy
-
Custom carousel only (no react-slick)
- Copy
Carousel.jsxanddata.js. - Import your data array (same shape:
id,image,name,title,quote). - Copy the relevant parts of
index.css(e.g..slider-container,.slide,.prev/.next,.person-img, etc.) into your projectโs CSS.
- Copy
-
Slick carousel only
- Copy
SlickCarousel.jsxanddata.js. - Install:
npm install react-slick slick-carousel. - Import slick CSS:
import 'slick-carousel/slick/slick.css'; import 'slick-carousel/slick/slick-theme.css'; - Copy the
.slick-containerand any overrides fromindex.css.
- Copy
-
Different data shape
- Keep
idand the fields you need (e.g.image,name,title,quote). Rename or add fields indata.jsand update the JSX in the component (e.g.person.headinginstead ofperson.name) and styles as needed.
- Keep
-
Props for reusability
- You can extend components to accept props, e.g.
data,autoPlayInterval,showDots, and pass them from a parent. The current code uses fixed data and intervals for simplicity.
- You can extend components to accept props, e.g.
- API: None. All content is from
data.js. Image URLs in the data point to external hosts (e.g. course-api); there is no project-specific API. - Backend: None. The app is static front-end only; build output can be served by any static host (e.g. Netlify, Vercel).
- Routes: There is no client-side routing. The app has a single view: the root component that renders one (or both) carousels. If you add a router later, you would wrap or replace the content inside
App.jsx.
- React: Functional components, JSX, props, state, and hooks.
- Hooks:
useState,useEffect,useCallback(and why dependency arrays matter). - State: Single source of truth for current index; updater form for correct async updates.
- Side effects: Timers in
useEffectand cleanup to avoid leaks. - Lists: Rendering lists with
.map()and stablekey(e.g.id). - Third-party libraries: Using and styling react-slick.
- CSS: Layout (positioning, transform), variables, responsive rules.
- Accessibility: Semantic HTML and focusable controls.
Keywords: React, carousel, slider, image slider, useState, useEffect, useCallback, react-slick, hooks, Vite, JavaScript, CSS, UI components, learning project, testimonials, front-end.
- React Documentation
- Vite Guide
- React Slick
- Slick Carousel (original)
- react-icons
- Live Demo: https://auto-image-slider.vercel.app/
This project is a practical way to learn React state and effects by building a custom carousel and comparing it with a library-based one. You can run it locally, switch between carousels in App.jsx, change data in data.js, and reuse the components or patterns in other apps. No backend or environment variables are required to get started.
Contributions and suggestions are welcome.
This project is licensed under the MIT License. Feel free to use, modify, and distribute the code as per the terms of the license.
This is an open-source project โ feel free to use, enhance, and extend it further!
If you have any questions or want to share your work, reach out via GitHub or my portfolio at https://www.arnobmahmud.com.
Enjoy building and learning! ๐
Thank you! ๐
