Introduction
In this comprehensive guide, you’ll learn how to build a modern and responsive frontend developer portfolio using Next.js, Tailwind CSS, and Sentry for performance monitoring. With the increasing competition in web development, having a standout portfolio is essential to grab the attention of potential employers, and this tutorial will equip you with the skills to do just that!
Why a Developer Portfolio?
A developer portfolio isn’t just an online resume; it’s a creative showcase of your skills and projects. It reflects your expertise, style, and can demonstrate your knowledge of modern web technologies—including frontend frameworks and performance optimization techniques.
What to Include in Your Portfolio:
- About Me: A brief introduction about yourself, your skills, and experience.
- Projects: Showcase various projects you’ve worked on (links, descriptions, and technologies used).
- Technologies: List of technologies or frameworks you’re proficient in.
- Testimonials: Feedback from clients or colleagues.
- Contact Information: Make it easy for potential clients or employers to reach you.
Tools and Technologies You'll Use:
- Next.js: A React framework for server-side rendering and static site generation.
- Tailwind CSS: A utility-first CSS framework for rapid UI development.
- Sentry: An application monitoring tool to track and manage errors in production.
- GSAP (GreenSock Animation Platform): For smooth animations.
Setting Up Your Environment
1. Initialize Next.js Project
Begin by creating a new Next.js application. Open your terminal and run:
npx create-next-app@latest my-portfolio
After the setup, navigate into your project directory:
cd my-portfolio
2. Install Tailwind CSS
Install Tailwind CSS by running:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
3. Configure Tailwind CSS
Open the tailwind.config.js file and configure it like so:
tailwind.config = {
content: ["./pages/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {},
},
plugins: [],
};
Add the Tailwind directives to your CSS file:
@tailwind base;
@tailwind components;
@tailwind utilities;
4. Install Sentry
To track performance and errors, you should setup Sentry. Run:
npm install @sentry/react @sentry/tracing
5. Setup Directory Structure
Create a clean structure for your components and pages:
components/
Header.jsx
Footer.jsx
Projects.jsx
About.jsx
utils/
constants/
Building the Portfolio Components
6. Header Component
Create a header component that includes your name and navigation links to different sections of your portfolio.
Example of how to create the Header.jsx:
import React from 'react';
const Header = () => {
return (
<header className="flex justify-between items-center bg-white p-5 shadow-md">
<h1 className="text-2xl font-bold">Your Name</h1>
<nav>
<ul className="flex space-x-4">
<li><a href="#about">About</a></li>
<li><a href="#projects">Projects</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
</header>
);
};
export default Header;
7. Footer Component
A simple footer with your contact information.
Example of how to create the Footer.jsx:
import React from 'react';
const Footer = () => {
return (
<footer className="bg-gray-800 text-white p-5 text-center">
<p>© 2024 Your Name. All Rights Reserved.</p>
</footer>
);
};
export default Footer;
8. Projects Component
This component will dynamically load your projects from a constants file. Structure each project with relevant information like project name, description, and links.
Adding Interactivity with GSAP Animations
9. Implementing Animation
Install GSAP using:
npm install gsap
Create animations for each section of your portfolio.
Example:
import { gsap } from 'gsap';
const animateElement = () => {
gsap.from(".your-class", { duration: 1, opacity: 0, y: -50 });
};
Monitoring with Sentry
10. Integrating Sentry
Set up Sentry in your _app.js file and monitor errors as users interact with your portfolio.
import * as Sentry from '@sentry/react';
Sentry.init({
dsn: 'YOUR_SENTRY_DSN',
integrations: [new Sentry.BrowserTracing()],
tracesSampleRate: 1.0,
});
Conclusion
You now have a complete modern frontend developer portfolio built with Next.js and Tailwind CSS. You can customize the styles, add functionality, and showcase your skills effectively. Make sure you monitor performance with Sentry to keep everything running smoothly. Happy coding!
do you want to stay ahead of AI by learning modern frontend skills that even Devon can't beat this video is what
you need gone are the days when people were happy with plain old websites that Bots like vz. deev can now create with
ease now is the time to step up your game and build websites that outshine the rest so hi there and welcome to a
new course where you'll build and deploy not one not two but three stunning uiux websites turned into an ultimate course
designed to transform you into a front-end developer ready to get hired will'll kick things off with a crash
course on gap for building silky smooth animations and 3js for giving websites that 3D feel after which you will clone
the iconic Apple iPhone website then we'll develop a visually stunning landing page featuring exciting
animations Parallax effects and a Sleek Bento grid your users won't be able to look away and lastly you will showcase
your newly acquired skills with a minimalistic yet striking developer portfolio impressing potential employers
with both your creativity and Technical expertise and are you worried that this is a bit too advanced fear not I'll
break down everything from Gap and 3js for 3D effects to tailman CSS for styling all in a beginner friendly
step-by-step way so by the end of this course you'll have a unique set of front-end developer skills and the
confidence to build responsive web applications that leave a A Lasting Impression here are the projects you'll
build the first project is the iconic 3D Apple iPhone website clone yes we'll code an iPhone 15 Pro clone using
nothing less than Gap and 3js but we won't just clone the site we'll start with a detailed crash course on how to
create powerful animations using Gap after which I'll teach you the Core Concepts of 3js and 3D development and
then you'll build the Apple clone website that has custom animations with scroll triggers staggers timeline and
more a custom video slider with progress tracking animated 3D models with different configurations lights and
viewports and other sections with cool animations complete responsiveness and Optimal Performance then you'll develop
a modern UI X website called brainwave you'll build a beautiful hero section with different shapes reacting to your
cursor a Navar with a colorful button that transforms into an animated hamburger menu when you're on smaller
screens and look at that subtle smooth scroll Parallax effect that moves these elements down as we scroll moving on
we've got a nice Services section featuring gradient borders on the cards and unique curved rectangle shapes each
of these cards also reveals a hidden background image next we have a pattern that showcases the most important
elements in a circular layout after that is a very fresh and modern web development layout called Bento Box many
popular companies like apple linear and clerk use this layout to display their features effectively below there's an
always needed pricing section after that there's a great style layout presenting the applications road map with gradients
grid lines highquality images and geometry lines on both sides creating a modern look lastly there's a simple
footer where we connect to the website social media pages and to feature all of your work you'll develop a modern
developer portfolio with a modern hero section with spotlights and text animations latest Bento grid design
here we went a step further and animated some parts into this grid for example this globe is a real 3D Globe which you
can move around then we have our text tack right here some more information about yourself even some code blocks and
then this nicely animated bottom part that allows your users to copy your email moving below we have a small
selection of recent projects and what's cool about this and the previous section as well is that we're not only using
Tailwind we're also using exterity UI which gives us a lot of these outof thebox frameware motion animations and
that makes it look different from anything I've seen so far testimonials and companies you've worked with also a
section about your previous work experiences about being a front-end engineering intern mobile appdev
freelance project and so much more and don't forget if you scroll up you have this nice bar that pops up that allows
you to scroll to different sections moving forward we have my Approach which tells employers how you work starting
from planning and strategy to development and progress updates to development and launch so you're not
just doing development you're doing so much more than that and a short but sweet footer section alongside building
these great projects you will also learn learn nextjs with server and client side rendering routing and layouts for better
performance and SEO Tailwind CSS for a modern completely mobile responsive UI 3js Gap and exterity UI to create
mindblowing animations functional components and how you can reuse them to make your code more efficient the best
file and folder structure for organizing your code like a pro and much more we'll go beyond just building your websites
and I'll teach you how to deploy them to hostinger fast servers and get your custom domain name but we're not done
yet we'll also use Sentry to track your app's performance like how many people visit how fast it loads what users are
looking at how much each operation takes which parts of the code are slowing things down how fast each component is
loading and see if there are any issues with specific devices and what about the prerequisites well all you need is a
basic understanding of JavaScript and react plus I highly recommend taking our tailin CSS crash course to get the most
out of this course now with even better teaching methods where you'll get an open- Source codebase you can look at if
you get stuck a custom figma design so you know exactly what you're building and a Discord server to get all your
bugs resolved all of these things are free so get them immediately from the links in the description while the intro
is rolling and since my goal is to make sure you land a job your portfolio will not be like any other project it's a
career asset designed to Showcase everything you're capable of making you an attractive candidate for any job see
hosting your portfolio on a personalized domain makes you more professional and improves your credibility and search
engine visibility it also speaks about your skills in self-hosting scaling and managing websites effectively so before
we dive into coding we need to set the foundation for hosting all of our projects especially the modern portfolio
and right now they're offering in a great deal which you don't want to miss when it comes to hosting This Modern
portfolio I personally go for the Premium plan and here's why it's perfect for this and many other projects you can
host a 100 websites with the same account you get a free domain name which gives you a professional touch you get a
free SSL for https security which creates trust with anyone visiting your portfolio this deal won't last forever
and because we've partnered with hostinger you get an even bigger discount so once you visit the link in
the description click claim deal and add to card here we have to choose the period of our hosting with a crazy
discount going on right now I'll definitely choose 48 months to save the most money and down below you can choose
your payment method and enter your JavaScript Mastery coupon code which will give you an even bigger discount on
your hosting package once you've made your purchase we are ready to set everything up and get started with
building out our portfolio let's start with hostinger guided setup we are building a new website so we can choose
create and we're building a completely custom website so we Cano choose skip at the bottom next we need to choose our
domain as you can see I use hostinger for my Js mastery. proo platform so here you can type out your domain name I
would recommend something like your first name and last name.com something like John doe.com and if you purchase
the hosting for more than one year you'll get the domain completely for free choose it and click next the domain
is registering and while that is happening I quickly want to point your attention to our improved Discord server
where now we have dedicated forums for each video so if you're building this portfolio and you get stuck you just go
to the Forum and ask a question this is the best way to get help now already we are the next step where you can choose
where your audience is located at and you can see there's a lot of options click next and the setup will initialize
while that is happening just another quick note and that is that the full codebase of the video you're about to
build is live on GitHub so you can check it out right here and if you don't mind give it a star with that in mind we are
redirected to the dashboard of our hosting project so finally let's let's code it out and we'll deploy it at the
end of the course ever caught yourself endlessly scrolling through the Apple's website fantasizing of owning the latest
iPhone yeah we all been there but have you ever wanted to actually create something as slick as what Apple
showcases hi there and welcome to a new video where I'll teach you how to build stunning apps like apple does for its
products yes we'll code an iPhone 15 Pro clone using nothing less than Gap and 3js but we won't just clone the site
we'll start with a detailed crash course on how to create powerful animations using Gap after which I'll teach you the
Core Concepts of 3js and 3D development and then you'll build the Apple clone website that has custom animations with
scroll triggers staggers timeline and more a custom video slider with progress tracking animated 3D models with
different configurations lights and viewports and other sections with cool animations complete responsiveness and
Optimal Performance will go beyond just building and deploy your website to hostinger fast servers but we're not
done yet we'll also use Sentry to track its performance like how many people visit how fast it loads what users are
looking at and see if there are any issues with specific devices alongside the video I've also prepared the
ultimate 3js and gep guide that covers a step-by-step road map inside their tips examples and cool project ideas to take
your animation and 3D development skills to the next level the link to this completely free guide is in the
description so are you ready to dive in and learn Gap 3js and then put that expertise the work by cloning the iPhone
15 Pro website let's go green Soxs animation platform often referred to as just Gap is a high performance
JavaScript animation library that allows you to effortlessly animate any anything JavaScript can touch you can animate
anything from uis and svgs to creating immersive 3D experiences from exciting scrolling animations to changing shapes
of objects text effects and UI interactions there isn't a thing you can't animate with gap any exciting
website you see with animations Parallax effects or fancy scrolling tricks is likely made with gsap from making basic
HTML elements move smoothly to creating entire animation timelines more svgs customizing bounce and wiggle effects
simulating physics and more Gap is the all-in-one solution for all of your web application animation needs Gucci
Spotify Nike Shopify and even Google all use gsap but there's also framer motion known for its gesture-based interactions
and its declarative syntax which tightly integrates with react for simpler animations in react it's the Top Choice
both animation libraries have their own unique use cases but here's where Gap takes the throne Gap is known for its
exceptional performance even in complex animations it's optimizations keep the animation smooth making it the go-to
choice for applications in which performance matters Gap also offers a high level of flexibility and control
over animations allowing you to create complex sequences timelines and effects Gap is extensively tested and supported
across many browsers and devices ensuring consistent an animations for all users even on all the browsers and a
rich feature set allowing you to do anything from simple effects to Advanced physics-based animations now let's move
to the second most important technology in making our apps interactive it's 3js and it'll shape the future of the web
with advancements in virtual reality and wider access to more powerful devices 3D development is just warming up before
3js creating 3D graphics for the web was a complex task web developers had to rely on low-level apis like webg or
special plugins like Adobe Flash or Unity remember those which were a pain in the ass with limited browser support
and extreme use difficulty with the growing demand for immersive web experiences and increasing strength of
modern browsers developer needed a better solution for 3D apps 3js came in and filled this Gap by abstracting away
the complexities of webg and providing a userfriendly API for building 3D scenes directly in the browser using JavaScript
some of the key features are the abstraction of webgl 3js abstracts away all web gl's complexities providing a
higher level API that simplifies the process of creating and rendering 3D Graphics it has a high crossplatform
compatibility making apps work seamlessly across different devices and browsers
it provides a rich set of tools and utilities for creating immersive 3D experiences including support for
lighting shading textures animations and interaction it's also very fast using web gl's Hardware accelerated rendering
3js ensures smooth and efficient performance even for complex 3D scenes and finally it also has an active
community of developers contributing tutorials examples and plugins making it the go-to choice for developing 3D apps
and starting to learn 3js is like diving into a new and exciting world with many features and Concepts to learn to
properly learn 3js you'll have to move away from the 2D vision and start seeing websites in 3D in a 3D space objects
possess threedimensional properties like length width and height or in math X Y and Z unlike the two-dimensional World
which we typically interact with on screen 3D space adds depth allowing for a more realistic experience each point
in a 3D space is represented by a set of coordinates that specify its position from the origin now I want to teach you
the most important Concepts in 3D development first is the scene it's the canvas where all the objects lights and
cameras are placed the environment in which the 3D World exists and where interactions
happen then there's the renderer which converts the 3D scene into 2D images that can be displayed on the screen it's
responsible for rendering the scene onto the browser the camera plays an important role in defining the Viewpoint
from which the scene is viewed it determines what is visible in the rendered scene cameras have properties
like position rotation and field of view that determine their behavior and how the scene is rendered 3js supports
different types of cameras with special behaviors like a perspective camera which mimics the way human eyes perceive
the world creating a sense of depth and perspective and an autographic camera which renders objects without
perspective which is useful for technical drawings or 2D games lights illuminate the scene and affect the
appearance of objects 3js supports different types of Lights including ambient light which adds overall
illumination to the scene without a specific Source directional light which emits light from a specific Direction
like sunlight Point light which emits light in all directions from a single point in space Spotlight which emits
light in a cone shape from a specific position and Direction and there are many more lights have properties like
color intensity and position that control their behavior and influence on the scene so now that we have the scene
the camera and the lights we can finally see some things within the space and the first thing we can easily show would be
be a mesh a mesh is the basic building block of 3D objects in 3js it consists of vertices points in 3D space connected
to form faces meshes Define the shape and appearance of objects in the scene and each mesh is associated with a
geometry and a material geometry defines the structure and shape of a mesh by specifying its vertices faces and other
attributes 3js thankfully provides a wide range of built-in geometries like box geometries spheres planes cylinders
and more you can also create custom geometries by defining their vertices and faces manually which will later on
allow us to see such a detailed 3D Apple iPhone model then there's material material determines the appearance of a
mesh including its color texture and how it reacts to light 3js offers some built-in materials like mesh basic
material which is simple and is not affected by lighting mesh Fong material which reacts to some light sources and
then the standard material which is a physically based realistic rendering and there are many other materials as well
which you can customize by adjusting properties like color opacity highlights and more and these were all the basic
building blocks of 3js and 3D development of course you can find their detailed instructions alongside a cheat
sheet in the guide down below but but 3js also has some more complicated stuff like shaders tweaking with meshes and
animating things around I'll show you how to animate 3D models using Gap in this video but going into detail on all
of these things would make this video too long so if you want a full crash course on 3js just drop a comment and
let me know and before we dive into the main star of this video which is of course cloning the 3D Apple website with
3js and GAP let me provide a conclusion on this part of the crash course which is how to use 3js there are a couple of
ways in which we can use 3js depending on Project requirements and your preferences you can use 3js directly in
vanilla JavaScript without any additional libraries or Frameworks all you have to do is put a CDN script tag
for 3js but of course you can also integrate 3js with Frameworks such as react View and angular each one of these
has its own way of integrating 3js we'll use react 3 fiber which is a library that allows us to easily integrate 3js
into react applications and it even makes it possible to create 3D scenes with react components so just so you
know you'll learn react 3 fiber in this video as well so just to give you an example in vanilla JavaScript you would
have to first set up the scene by saying scene camera and renderer figure out where you want to render the canvas and
then add a cube to the scene and maybe even a plan animation in react 3 fiber it's much easier and much more similar
to what you're used to you simply import the canvas and the used frame from react 3 fiber and then you import the box or
some other element you want to show and call it using Hooks and show it with react components react through fiber
acts as a wrapper which makes it easier to add 3D scenes to our react applications enough with Theory let's
dive into action I prepared a quick workshop for you and I've linked it for for you in the description download it
open it within your Visual Studio code and then we can install all the necessary dependencies by running mpm
install this is going to take just a moment as we don't have too many dependencies as a matter of fact we can
look into what we do have and you'll notice that it's basically just react react Dom and react router Dom with some
Tailwind CSS so the entire setup is completely empty will explore everything from scratch so let's go ahead and run
the application by running mpm run Dev to see what we have on it and then we can hold the command key and click on
this link to open it up as you can see I prepared seven different demos that teach you seven most important Gap
Concepts so let's dive into the first one by clicking right here and let's explore gp. 2 gp. 2 method is used to
animate elements from their current state to a new state it's similar to gp. from but the difference is that the gsap
2 method animates elements from their current state to a new state while gsap from animates elements from a new state
to their current state and of course you can read more about it if you head over to the documentation page basically you
can see how it works right here you target a specific element by providing the identifier and then you specify the
properties that you want this element to take after the animation runs so we are changing the rotation and the exposition
throughout the duration of 1 second so now you've seen the demo right you could have done on your own without me but see
this box right here now we'll animate it together to solidify what we just learned so going back to the code we can
split our terminal and install a new package by running mpm install Gap as well as at Gap SL react which will allow
us to start adding those animations once that is done we can head over to our pages and then Gap 2 as that is the
first element we want to animate in this case I want you to animate the box that we have right here below so if you
scroll down you can see a div that has a class name of VW HW and then BG blue 500 which makes that a box and here we have
an ID of blue box so let me teach you how to animate using gab in react right below this Todo we can say use Gap
coming from Gap react this is a special hook which looks and behaves a lot like use effect essentially you define a
callback function and then a dependency array on when this has to run and within it you can use Gap to then animate the
elements you want so we do that by saying gap which you have to import from the original Gap package do2 and then
the first parameter to the do two method is the target you want to animate in this case we can Target it by ID by
saying blue box then the second parameter are variables which you want to animate so
you can expand an object and let's do something like X is 250 pixels so we animate from X of zero of course by
default to X is 250 so now if you go back to your page and reload you can see how nicely this animates and just so we
can see our animation Happ happening in real time at all times without needing to reload the page we can add a repeat
of minus one as well as a yo-yo property set to True which will make the animation reverse on every other cycle
so as you can see now it's going back and forth let's pull this to the side so we can continue animating while we're
writing the code at the same time there we go that's much better now let's also give it a bit of a rotation property of
360 and you can see now it completely rotate and you can see now it completely
rotates we can also increase the duration to something like 2 seconds if you do that it's going to move much
slower and we can also give it a special ease property which defines how the animation happens as you can see
immediately you get a lot of different properties you can choose from for example bounce in if you save it you can
see now it kind of bounces in and then stops you also have bounce out which going to make it bounce at the end
there's a lot of these different easing curves that you can decide to use there's also Circle back and so much
more in this case let's use elastic as you can see it looks like it's on a spring right now which you have to pull
and then move back and forward which gives it a very interesting effect but with this in mind you just learned how
to use one of the fundamental methods in gsap which is gap. 2 property which accepts an ID which is an identifier and
then properties you want to apply to the element you're targeting you also learned how to apply animations using
the used Gap hook and gsap within react so with that in mind let's go back to the homepage and navigate to the second
method of the day Gap from as the name suggests Gap from is used to animate elements from a new state to their
current state similar to GP 2 but the difference is that the from animates from the new to the current while GP 2
animates from their current to a new state of course you can find more information within the docs but for now
let's implement it in action I'm going to go back to gap. 2 and copy this entire
part then I'm going to navigate to Gap from and simply paste it right here below of course not forgetting to import
the used Gap as well as Gap now if we modify the method from to to from and modify the ID from blue to green and
save you can see that it started moving from the back and then going to the front in this case let's explore a bit
of a different ease one I like to use often which is power one.in out this one starts with a lot of power and then
slows down as you can see it right here but the most important thing is that now it starts from the position 250 pixels
in if I load see how it started from the right side moving to the left that is the only difference between from and to
the next method of the day is Gap from two which as the name suggests is used to animate elements from a new state to
a new state similar to from and two methods but the difference is that here you can Define both States so if we
scroll down we can copy the entire thing we have here and navigate to from two so let's paste what we copied import the
hook as well as Gap we can modify the method from from to from Two and you still pass a
specific identifier but this time you have two different objects you can modify we have the first object which is
the from object and then we have the two object which accounts for the two properties we want to implement so let's
try to animate it from an X of zero and a rot of Z with something like a border radius of 0% as
well and we're going to animate it to 250 repeat minus one and let's also add a border
radius of 100% And we can also modify the ease to something like bounce out to explore another one now if we modify the
identifier from Green Box to Red Box and save it now you can see how it turns from a square into a circle and then
comes back so we're modifying the rotation and the X and the Border radius to zero at the start and then at the end
we set it to 100 which essentially makes it a circle this is pretty useful when you want to modify both the start and
the end of an animation with that in mind those have been the three base Gap methods but let's explore what else we
have in store next one on the list is the GP Tim line and the gep timeline is used to create a timeline instance that
can be used to manage multiple animations again it's similar to two from and from 2 but it is used to manage
multiple animations while all of these manage just one element from their current state to a new state of course
we can open up the docs to learn a bit more about it and in this case you can see that they consider it a sequencing
tool that act as a container for the other animations we have explored it allows you to have complete
control and manage the timing of an animation so instead of doing something like this first do X100 then do y50 and
then change the opacity to zero you can create a timeline and then you can modify the elements to move on that
timeline you can also control the whole thing easily by pausing it resuming it reversing it and so much more so with
that said let's animate this yellow box and also include the play and pause button so we can navigate over to Gap
timeline and you can see at the bottom as we always do there is a div that has an ID of yellow box so first things
first when creating a timeline we have to Define it by saying const timeline is equal to gap which you have to import
from gap. timeline and then you call it like this next you can also pass the options
object to give it some properties like repeat minus one repeat delay of something like 1 second and yo-yo to
true we already learned what this does it simply makes the Box move left and right it simply makes the animation
repeat so we don't have to reload the page to check out the animation now that we have the timeline defined we can use
the same use gsap hook we have used not that long ago Define the Callback function as well as the dependen array
now within it we can use the timeline. two property instead of using the gap. two property and it works in the same
way you have seen it before it's just timeline. 2 you then Define the identifier which in this case is the
yellow box and the second parameter are the variables you pass to it such as the x is 250 rotation is 360 border radius
is 100 per duration is two and then ease is back do in out again this doesn't matter
too much right now but we're just playing with the way that the animation actually executes so if we save it now
you can see how it goes from one end to another and comes back now what we can do is we can also say
timeline do 2 again Target the same yellow box and then provide another another set of variables we want to
apply to this animation such as X500 scale of one rotation of 360 border radius of something like 8 pixels
duration of two and ease of back. inout now if I save this you can notice that it's yellow and then it goes further out
of the screen I'm going to zoom this out a bit so you can see the full animation first it goes to 200 50 Waits a bit and
moves to the end and then it returns now this is a bit similar to using the from and to or the FR 2 but what this allows
us to do is to add additional animations in the middle so we can say timeline. two once again where we target the
yellow box and this time we can for example do the Y of 250 scale of two rotation of
360 border radius of about 100% And duration of two as well as the ease back do in out now if we save this we have
added a third animation to the mix where now it will actually go down out of the screen move back and then it's going to
come back again so these animations are happening in a row one after another which gives you a lot of possibilities
to control the entire timeline now another another thing you can do here is of course play and pait because you have
complete control over the timeline so let's head over to our play and pause button which is right here and let's
expand this on click functionality we can define an if statement and say if timeline. paused is true then we want to
trigger the timeline. playay and also else vice versa then we want to run the timeline Dot pause so if we do this and
save now you can click play pause and completely pause the execution of the animation then you can trigger it again
and it works so I think you can see the benefits of running animations within a timeline you have more control now let's
move over to the fifth method in the Gap repertoire stagger Gap stagger is a feature that allows you to apply
animations with a staggered delay to a group of Elements by using the Stagger feature you can specify the amount of
time to stagger the animations between each element as well as customizing the easing and the duration of each
individual animation this enables you to create Dynamic and Visually appealing effects such as staggered Fades
rotations movements and more and of course you can find more within GP stagger documentation they even prepared
a little video but in essence it is as easy as using the Stagger property so let's explore it in Act ction by
navigating over to the Stagger file in this case if you scroll down you'll notice that we don't have a single box
with an ID of box rather we have multiple divs that all have the same class name stagger box so instead of
Simply using an ID we'll use the class name as an identifier so same thing goes we can use the use Gap hook create a
callback function and then we can use the gsap do2 method and in this case we can
import Gap from gsap now you might say hey we already learned two but we haven't used stagger well stagger is
just a property you can apply to any animation so we'll use two to show this out to explain the Stagger by targeting
the Stagger dashbox and then we can provide the options in this case we can do the same thing we've done before such
as y of 250 rotation of 360 border radius of 100% to turn it into a circle we can add a repeat of
minus one as well as a yo-yo of true now if we save this you can see they all follow the same animation as we're
targeting all of the elements simultaneously but what if we want them to animate one by one well in that case
we can provide a stagger property of 0.5 let's say so now we can save it and you can see that now after half a second
each one of this animates one after another but it doesn't end there we can also apply more complex stagger
Properties by defining stagger as an object here you can provide the amount which is the amount of time to stagger
the animations between each element and we can say something like 1.5 then you also have access to something known as a
grid grid selects the number of columns and rows in a grid so you can say something like 2
1 then there's also the axis and you can choose the axis along which the stacker the animations in this case we can say y
but you could also say X in which case they all happen at the same time next you can also apply the ease which in
this case we can do something interesting like Circ dot in out and how kind of they happen in a circle and
finally this is the most interesting one you can Define the from which is the starting position of the staggered
animation so instead of starting from the start or the end we can say Center so this will make it start from the
central staggered box as you can see now it happens from the start and moves until the end and
you can also see how they're doing two and then one and so much more so you have complete control over how you want
to stagger your elements this is great so now you know how stagger works and how you can use it when you have
multiple Elements which you want to animate and let's call it a dance of sorts the next feature on our list is
the scroll trigger which is use the trigger animations based on the scroll position so as you scroll you can
animate specific things once you reach a specific point in time so for example scroll down to see the animation and
then only after you reach a specific point we want the animation to start so let's first open up the documentation
page and I always advise you to read the doc for anything you're doing there's also a quick video right here and the
simplest way is to attach a specific Target which when it enters the viewport or the screen then the animation happens
or you of course have much more control over when what over when the animation triggers in this case we can go back and
go to Gap scroll trigger and let me show you how to implement it first of all it's very important to note that GP
scroll trigger is a plugin which means that we have have to initiate it at the top by saying import scroll
trigger from Gap all and then you can do gap which we have to import from gap. register plugin and then you pass that
scroll trigger this will make it work next with triggers you also have to define a ref a reference so we can say
scroll ref is equal to use ref coming from react this is not Gap related this is
just react then we can use the same old use Gap hook coming from Gap react which we
can Define like we have done so far now in this case if you scroll down you'll be able to see that we have some boxes
right here now if you scroll down let's attach that ref to our boxes so if we scroll here you can see that we have two
boxes the scroll pink and scroll orange and we can attach a r to this div wrapping both of them by
saying ref is equal to scroll ref like this now we can scroll to the top and we can start animating so first let's get
access to those boxes by saying const boxes is equal to gap. utils do to
array and to it we pass the scroll ref. current. so this is how we can get the children
using a react ref next we can also run the boxes dot for each so for each box we
want to do something and that something will be a simple gap. 2 animation where we target each individual box and for
each one we apply some specific properties in this case we can say x is something like
150 rotation is is 360 border radius is something like 100% scale is 1.5 we have learned that
already right so now if we scroll down you can see that they basically already turned into circles even though we
didn't see it at all because we were at the top when the animation was happening not too useful right typically you want
to have some animations when you scroll up to a specific point like if we're here we can see it sure but the user
will come from top and then we'll start viewing this at the bottom so this is where scroll trigger animations come in
to this gsap 2 property we can apply a scroll trigger which is an object to which you
can pass a trigger and then this one will be a box so one specific box comes into view we want to start the animation
let's see that once again if I start scrolling down already it's a circle but that's
because we're missing something important we're missing the start of the animation which we can Define as bottom
bottom so when the bottom of the Box hit the bottom of the viewport then it will animate and we can also Define when it
will end and it will end when the top of the box hits 20% of the viewport we also have something called scrub which we can
set to True which makes the animation smooth and below the scroll trigger we can also Define the ease of power one do
inout and the reason why the scroll trigger animations are not working is because I misspelled it as scroll
instead of scroll with a double l so if we fix this now check this out I'm going to scroll to the top reload the page and
start scrolling down so now as we enter the viewport slowly you'll see how this starts as a box because that's what it
Styles say by default and then slowly it starts moving to the right and it starts supplying the rotation border radius and
scale as we scroll check this out interesting right and also it goes back immediately now another thing is
that since we're mapping over those boxes we can apply a bit of math to each one so instead of just moving it x 150
for each one we can multiply that by boxes do index off a specific box so this will already
apply it a bit differently because the second one has an index of one and we can also give it some default value like
plus 5 so now if we start scrolling down you can see how nicely they animate and exit out of the screen we come back they
are back and of course you can keep playing with these value like top 30% which will make them go away much sooner
or like something like top 10% which will make them in the screen for a longer period of time it's up to you to
start playing with this and I just noticed we don't need a comma right here it's just bottom bottom so like this
yeah that's great another thing you can add when you're animating using the scroll trigger is if you go all the way
to where you end the used gep function which is here you can also provide a second parameter of scope is scroll
ref like this that way it will know exactly when the animation has to happen so now I'm sure you have already noticed
how useful GP is specifically simple properties like GP 2 staggering and so on but only when you pair it with scroll
triggers which will do a lot within this video and it's also covered in a lot of depth within our ultimate guide which
you can find in the description down below completely for free you notice how it all starts coming together when you
combine all of these properties and finally we have Gap text where I'm going to teach you how to animate text
elements with gap so to animate text you can use all the methods we have explored so far the only thing you have to do is
integrate the text plugin you can see it in the docs basically you can add the Gap 2 and then add the text you want to
animate you also have some special properties for animating text elements so let's head over to text and you can
see an H1 here that says Gap text but it's nowhere to be found on the screen it's kind of like it's being hidden
right and that's because it is at the start the opacity is zero so let's go ahead and animate it in we're going to
use the same old tips and tricks like use Gap coming from Gap react where we have our callback
function then we will Define gap. 2 which we have to import from Gap we target the text element by ID of text
and then we provide some properties like ease which will be power one.in out once again you can go with without this or
you can find the ones that you like and then add different eases and then I'm going to add opacity of one as well as y
of zero so this is nothing new right we're just changing some properties using gsap 2 and you can see how nicely
it slides in great now let me also teach you how to animate the paragraph you can see this par class name right here it
combines all of these properties that you can see so let's add a gap. from two in this case and we can Target the para
which is the paragraph and then as you know with from 2 you have to Define two different
objects and at the start this text is visible we didn't apply an opacity zero like we did here so you can apply it
here in from opacity 0 y of 20 and then of course it's going to break until you provide a second object where you can
reset the opacity to one and Y to zero so now you can see how nicely it fades in we can also apply other things we
learned such as the delay between the elements as well as the Stagger of 0.1 so now different paragraph elements
are going to animate one after another and with that we came to the end of this little Gap Workshop as I said we go into
more detail on all of these and many other more advanced Gap properties within the ultimate Gap and 3js guide
which you can find below so check it out and get warmed up for the main star of the show which is diving a bit into 3js
and then combining the 3js knowledge with your gep knowledge and building something on your own it's one thing to
watch me do things and then enter a couple of methods and it's a completely different thing to build something truly
useful and replicate what some of the best companies in the world do so how do you feel about these Gap features we'll
explore everything in more detail later in the video Gap also offers plugins for physics and motion that allow you to
create animations with realistic physics-based motion such as bouncing elasticity and acceleration and yes I
know we covered a lot of ground regarding Gap in a short amount of time which is exactly why I prepared a
complete GP guide and cheat sheet down below so download it and save it somewhere for reference it's completely
free also leave a comment down below below if you're interested in a more detailed and more advanced Gap crash
course but with that said that's enough Theory so let's get started to get started with building our amazing 3D
Apple website we'll begin from bare Beginnings by creating a new empty folder on our desktop I'm going to
rename it and call it applecore website and then drag and drop it into an empty Visual Studio code
window once you do that we are ready to set our project up to quickly get ready with our development environment we'll
use vit it will allow us to quickly spin up a react application with a lot of interesting things provided out of the
box like the instant server start optimized build hot module replacement and more but of course if you want to
build this project out with another technology like Vue angular or even better NEX GS I would be more than happy
for you to do that you're going to learn even more by building it in your techn you of choice so with that in mind we'll
use vit and with vit we'll also use Tailwind CSS which is a utility first CSS framework packed with utility
classes for easier styling so with that in mind let's go to Quick Search and let's search for vit or your own
preferred framework once you're there we can copy the command and quickly get started with our application back in our
editor I'm going to press control backtick which is a shorthand for for quickly opening up the terminal or you
can go to view and then terminal once you're there you can paste the First Command that we copied but I'm going to
change my project with Slash which will ensure to create all of the necessary files and folders right within the new
Apple website folder we created so press enter it's going to ask us whether we want to install the create V CLI to
which we can say why yes and then run mpm install to install all the necessary dependencies and once that is done let's
follow the next steps right here you want to install all of the necessary Tailwind config so let's copy this mpm
installed Tailwind CSS post CSS and auto prefixer paste it here and press enter let's also initialize a Tailwind
project next we need to update our template paths by copying this content navigating over to Tailwind doc
config.js and by the way Pro tip the way I just navigated is by using command or control
and then P you can start typing and you can immediately press enter to navigate in another file or of course you can use
your mouse and go right here with that in mind I'm going to update our content and then we can follow the next step
which is to add tailin CSS directives to our CSS by copying it going to our index.
CSS removing everything and pasting just these three tailin directives once we have that we can add a simple
H1 to our app so let's navigate to our app.jsx remove everything from the return statement like this and simply
return a simple H1 while we're here let's also remove all of the other things that we don't need and we can
also remove the app CSS as well as removing that file as it's creating clutter
there we go we can also rename this to an es6 plus arrow function there we go so now that we have
this let's reopen up the terminal and run mpm run dev then you can hold command or control and then click right
here to open it up on Local Host 5173 and we are in we can see that the text is enlarged underscored and bolded
which means that Tailwind CSS classes are getting applied properly now let's turn this empty canvas into this a
modern 3D Apple website with gsap animations and 3D models and before we begin another Pro tip for new developers
out there you might notice that my browser is looking a bit weird this is not your typical Safari or Chrome
bookmark bar I'm using a new browser called Arc which is very convenient and allows you to focus on what matters it
is of course built on top of chromium so you always have all of the typical Chrome features you're used to and
they're available for Mac OS and as of recently for Windows 2o and now this is not a promotion I just wanted to share
it with you in case you're interested and before we begin setting up our file and folder structure we have to set up
our linting that will include es lint and prettier so in the description down below I created a special guide
containing the configuration that I personally use on all of my projects and the guide will look something like this
it is a 22 page PDF that covers es length prettier in Visual Studio code for both react and nextjs starting from
the introduction on what eslint even is and why do we need it and then moving on to a complete setup using nextjs but
what you're more interested in for this video is the setup for react all of that is included in this simple PDF and once
you get it you'll also be added to JSM weekly which is our official newsletter where every single week we share some
news from the web development World there is no ads just fresh information on react nextjs and web development in
general so download the guide implement the linting and we can continue now let's set up the base file and folder
structure and The Styling for our project first things first we want to navigate over to the Tailwind Doc
config.js and here we want to set up some basic colors so we can go under theme and under extend then extend the
colors that's going to be an object where we can add a color blue which is going to be #
2997 FF now every time you want to add a specific color you just say blue you don't mention these six random
characters and alongside adding the blue we also want to add a couple more colors and to quickly add them just just click
the read me link in the description navigate over to Snippets and then here you can find all the Snippets for this
video as you can see there aren't many the first one is the tail wi config JS alongside adding the blue we're also
adding a couple of variants of gray for our different text elements and a zinc color so let's copy this entire snippet
and let's simply override what we have here the second thing we want to add when it comes to styling is the
index.css so expand it copy it and then back within our code navigate to index.css
and override everything we have here you'll notice we have about 120 lines but all of these lines are helper
classes providing some text colors text variants and more so if we scroll all the way up you can see we're targeting
the body by making some default modifications and then adding some utility classes like nav height BTN
color container and more we'll refer to these throughout the build of this video but these are in no way all the Styles
we'll be using in this video you will write all of the Styles yourself these are just some helper classes to get us
going next in our file tree we also have the assets folder which for now simply contains the react. SVG icon we want to
remove that assets folder go back to the readme within links and then download our own assets containing all of the
assets for the build of this phenomenal Apple website including the 3D model we'll be using so click the link here
and simply download it from our Google Drive it's going to say we cannot scan it for viruses but I think you can trust
me on this once you download it simply delete this public folder right here and then drag and drop the new one into the
root of our directory click copy folder and here you'll notice that we have our 3D models as well as the Assets Now to
quickly use these assets within our code we're going to create a new folder called utils and within the utils folder
we'll create a new file called index.js back in a read me you can expand this
index.js copy it and paste it right here you can notice that here we're basically importing all of the images and then
exporting them so that we can quickly use them within our project and the last last last thing we need are the
constants these are some predefined arrays of information like content or text that we'll use within this project
for example see this enter a17 Pro gamechanging chip back in our app you can see where this text goes so what
we're doing here we're preparing the content for the entire application everything from nav items to footer
items and more so let's simply copy it and within the source folder create a new folder called
constants and create a new index.js file and paste everything we copied and as you can see there's zero logic happening
here just content which we can consume when we actually develop our website so with that in mind let's prepare for the
development by going into our index.html and let's modify our icon we can go from V SVG to a new icon coming
from our assets that's going to be public assets images apple. SVG so SLU SL assets
slimes slapp apple. SVG and we can also change the title of our application to Apple
iPhone and and save it now if we go back to the browser you can see that now we have this great looking Apple icon as
well as the title and we're ready to turn this into this so let's dive right into the development I'll start by
diving right into our app.jsx we want to remove this H1 and instead turn it into a main section and
give it a class name equal to BG Das black then within here we want to have a couple of components such as the Navar
the hero section and the highlights I think that's enough to get us going so let's create these three as
components by creating a new components folder and within there creating a new file called navb bar. jsx inside of
where we can run rafc and press enter this will quickly spin up a new react aror function
component called navbar and if this didn't work for you you need an extension called es7 plus Redux react
native Snippets so simply install it and it should work alongside the nav bar we're going to also get our hero section
by saying hero. jsx with rafc and we'll also get our highlights component where we can run our
afce now we have three three most important components well maybe second most important as our 3D model is the
star of the show so now let's go back into the app let's turn these three into a self-closing and self- calling
components and let's import them at the top by saying import navbar coming from slash components SL navbar and we can
duplicate this three times and rename the second one to hero and the third one to
Highlights finally let's see if we can see anything in our browser I'm going to pull our browser to the side and my code
Editor to the left now if I zoom this in a bit you can see that we have our navbar hero and highlights which gives
us a lot of room to start working on stuff so let's get started from top to bottom with the first component of the
day the nav bar to start developing it we can transform this div into an HTML 5 semantic header tag and within it we can
render a new nav tag this nav will render an image and that image will have a source equal to Apple IMG like this we
can import that Apple IMG at the top by saying import Apple IMG coming from d/ SL utils if we save it you can see the
Apple logo appear instead of the text that says navbar let's give it an all tag of Apple a width of about 14 and a
height of about 18 within this image we're going to have a div within this div we want to render all of our nav
items and that's going to be dynamic so we're going to have an array of something like let's say I don't know
phones we can also have MacBooks and we can have something like
tablets and we're gonna map over this array by seeing that map where we get each individual nav item and its index
and for each one we want to immediately return a div that will render that specific nav item this was supposed to
be a comma there we go so now we can see phones MacBooks and tablets we can also
give this div a key equal to the index that we're mapping over or in this case we could also just make that the nav
text itself because we know that it will always be unique finally going below this div we want to create another div
which will contain an image this image will be the search image so we can say source is equal to search image coming
from utils I just automatically imported it by pressing the enter key so you can see
it got it from here and we can also give it an Al tag of search as well as a width of 18 and a height of 18 as well
we can duplicate that below and we can also get the bag image from utils in case we want to buy something of course
I'm going to change the alt to bag if we save this you can also see the search and the bag all very minimalistic as
Apple always is is so now that we have the layout of our navigation bar let's start adding the
Styles I'm going to give our header a class name equal to w-o so it takes the full width of the screen padding y of
five to give it a bit of a padding top on small devices padding X of 10 to divide it a bit from the sides usually
padding X of five we're going to give it a Flex container like this where we want to
justify the items between and items Dash Center to vertically align them in the center of
the screen more importantly we want to make our inner nav a class name of flex which will immediately make all of the
items go one next to another we also want to give it a w full so they span across the entire screen and we also
want to give it a screen Max width so this will ensure that it takes the full width of the
screen now if we go into our index.css and at the top search for this screen Max width you can see that I misspelled
it as scrim so let me just say screen Max width and that way this will be applied and it will give it a Max width
of about 1, 120 pixels now let's style our class items by giving them a a class name of flex
that's going to make them go one next to another Flex off one justify Das Center and on Max Das small devices so devices
with a width of 600 and less we want to make it hidden because they don't all fit right so we can eventually expand it
but for now we cannot fit them all also it's not good to have this content right here and mess the content with the
actual jsx which we're presenting so with that in mind we can import this content from the constants by saying
import nav lists from SL constants that way instead of rendering this entire array here we can simply say
nav lists. map and this nav lists contains store Mac iPhone and support we cannot see it now because we have hidden
it on small devices but of course if we expand it you'll be able to see that it's there of course I need to zoom out
quite a lot there we go and go back great now let's style each one of our list items by giving it a class name
equal to padding X of five and it might be good to come back to larger devices so we can properly see it there we go
that's more Apple like let's also give it a text- smm so a bit smaller cursor Das pointer so we know they're clickable
text- gray there we go because we don't want it to take away from what's in the
middle of the screen we want them to buy the items on Hover we're going to make it a text of white and we're going to
give a small transition Dash all so that it nicely animates as you hover over it there we go
that is looking great now we can go back to a smaller screen and we can style the icons to the right side by styling this
div and giving it a class name equal to flex items Das Baseline gap of seven in between the elements on Max small
devices justify end and on Max s devices again Flex of one so this is going to make the items nicely appear on the
right side of course if you want to you can also add a hamburger menu but for now this is looking good to me and of
course it looks great on desktop devices as well this was just a super quick knv bar which means that we're now ready to
start focusing on the hero section so let's hold our Command or control and then click into the hero section to
start developing it our hero section will be just that a section so we can write section and then we can also give
it a class name of w- full for full width nav height which will make it come below the nav bar BG of black and
position of relative now within this section we're going to display a div with a class name equal to
h-5 over6 so this is a height of about 83% as you can see right here I can see it because I have a Tailwind CSS in
extension installed if you don't see this you might want to install it but now what does this mean you can see that
now it pushes the highlights below which means that the section is taking the full height of the screen let's also
give it a w- full a flex Dash Center and a flex Dash Co so the elements appear one on top of another within it let's
render a P tag and let's make it say iPhone 15 Pro there we go in the middle minimalistic
as Apple does it and let's give it a class name equal to Hero Das title now as you can see this hero title got
completely hidden away as soon as we added this class name why is that well if you're wondering what are the Styles
applied when we give a specific Tailwind class you can always copy the name of that class and then head over right here
paste it and find it within the index.css and here you can see that we are applying some things like text
Center font semi bold text 3 XL to make it bigger text Gray 100 but hey what is this why are we applying an opacity of
zero why are we hiding it well looking at the deployed site might give you a hint let me reload so you can see it at
the start the text was wasn't there but then it popped up that means that initially we want to hide this piece of
text but then we want to animate it in so let me teach you how to do that using Gap Gap is probably the best and a
widely robust JavaScript animation Library built for professionals let's scroll down a bit to see what they're
about they are going to allow you specifically yes you you because you're watching this video to effortlessly
animate anything JS can touch smooth performance and you can focus on the fun stuff IIM made literally anything it
looks great it feels great I think I'm sold right let's see how we can use it back in our code we can open up our
terminal split it to get a new one and run mpm install Gap as well as ADD gap for SL
react and press enter this just installed all the necessary libraries and it allowed us to import two things
import Gap from Gap and import use Gap coming from Gap SL react now right at the top we can call this use Gap hook
like this just as you would call any hook and to it you provide first of all the function containing your animations
and then dependencies when it is running so here we're going to have a callback function and then as the second
parameter we'll have an empty dependency array within here we can then use the base
Gap to animate something specifically we're going to say gap. 2 so we want to animate two specific values we know what
the default values are right right the text or rather the lack of text right here as the opacity is zero so given
that we know that fact we can now Target this element by a class or an ID and then give it a new value that it will
animate to so in this case I'm going to give this P tag an ID equal to Hero but you might as well Target it by a class
name if it's Unique then say hash hero as it's an ID and then here provide an object of the properties you want to
give it once it animates so that's going to be in our case opacity of one now if I save this you can see how
it nicely animated it was very quick though but you can also play with the delay or the duration in this case let
me set the delay to something like 1.5 seconds so if I do this you will notice that once you reload there's nothing for
one and a half seconds and then it animates in and with that my friend you have just implemented your first Gap
animation pretty simple right trust me we're going to get into much more complicated GP animations but be happy
that you've done your first one for now now the second thing is to get this video playing right here and yes it's a
video although you would never assume so so going below our P tag we can render a div and that div will render a class
name equal to on medium devices width of 10 over 12 which is about 83% and usually width of 9 over2 which
is about 75% within there we can render an HTML video tag like
this and we can give it a source this source is a self-closing tag that will have an SRC property of
video SRC like this which we can import at the top by saying import Hero video from do utils as well as small Hero
video why small well that's because we'll have two versions of the video depending if we're on desktop device or
tablet or if we're on the phone so let me show the that to you in action we can reload this screen and you can see that
here it's very small and narrow perfectly fits in your phone but if I go to a desktop device and reload you can
see that here we have a horizontal iPhone turning around how cool is that exactly like on the Apple website so to
achieve that we first have to figure out the width of the screen and for that we can use a use State hook and we can call
it video SRC so video SRC and set video SRC exactly what we have here under the source then here we want to figure out
what is the inner width of our window and we can do that by saying window. inner
width and if it's lower than 760 pixels then we make the video Source State equal to small Hero video else we make
it just a typical Hero video and of course we have to import use state from react now if we go back to our current
application and reload you can see that something happens in the middle but not too much happening yet so let's also
give it a type equal to video SL MP4 and in the video tag let's give it
auto play muted as we don't want any sound plays in line will be set to
true and we want to give it a key to this video which will be equal to video SRC if I save it you can see the video
started playing and it doesn't even look like a video we can also give it a class name equal to pointer-events
dnone so nobody can click it or mess with it so now if I save it looks great but if I expand my screen oh that's not
good right so let's make it dynamically modify the video depending on the width of the screen we can do that by saying
const handle video Source set like this and this will be a function that's simply going to look into the inner
width of the window by saying if window. inner width is lower than 760 pixels then we want to set the video source to
small Hero video and else we want to set the video source to be the big hero video or just
Hero video and now we can connect that to our use effect so let's create a new use effect hook like this with an empty
dependency array and don't forget to import it at the top then we can say window. addevent
listener and we're listening for resize of the screen and whenever we resize we want to call the handle video set source
and in react it's very important to clean up your event listeners as well which you can can do by returning a
function inside of which you can run window. remove event listener resize and that's going to be the handle
video Source set like this so this way you can notice that on big screen we're playing this wonderful looking
horizontal iPhone and on smaller screens we're playing this great looking smaller screen iPhone how cool is that so now we
can collapse these functions and we can scroll down to start adding our cold to action button to actually purchase this
gorgeous iPhone so let's head below the video and Below two more divs and let's create a new div which will have an ID
equal to CTA as in call to action and it will have a class name equal to flex flex-all so the elements appear in a
column items D Center to Center them on the screen opacity of zero and translate D
y-20 I think you already know why I added the opacity zero right we're going to animate it and I also added the
translate for the same reason this is simply going to translate it by 80 pixels to the bottom on the y axis so
later on we'll be able to animate it so that it flies up the screen so within this div we can create an anchor tag
that will have an href of hash highlights it's going to lead us to the Highlight
section and we can give it a class name equal to BTN here we can simply say buy now of
course we cannot see it yet and below this one we'll also add a P tag that will say from 199 bucks per month or 999
if you're purchasing right away we can give this P tag a class name equal to font
dormal and text- excl to make it a bit bigger but now I have a small task for you figure out how to animate this Viv
including the anchor tag and the P tag hint it's going to be happening within our used gab hook so pause this video
and give it a try what we can do here is once again call the gap. 2 function and then Target the
# CTA ID and we want to animate to the opacity of one and we want to also push it a bit up
by giving it a y AIS of minus 50 which will push it up and we can also give it a delay so that it happens hand inand
with the animation on of rh1 so we can say 1.5 seconds now you can see how both the
iPhone 15 and the buy button and the text animate in at the same time with the video so let's reload and see it all
in action the video shows up and then iPhone reveals itself and then we have the pieces to buy the text but hey we
don't want to buy it before we can actually see the iPhone right so let's bump up the delay to about 2 seconds
save reload the video shows up the iPhone comes up and then at the same time the
buy button and the iPhone text shows up how cool is that I'm very excited let's also check this out on the entire screen
by reloading checking it out and there we go the text is here as well who would
have said we have already developed the Animated Hero section of the Apple iPhone website but of course don't go
just yet as we have many more interesting things coming up such as this cool section where you can actually
move through different sections playing different videos and it all feels like it's a part of the website you can also
go down and then see the entire 3D model and you can move it around also you can change the colors and you can get to to
a bigger screen version as well how cool is that so with that in mind let's focus on developing the second section of day
which is this animated highlights section I'm going to bring my browser once again to the side close the hero
and the index and navigate into our highlight section to get started with our highlight section we can turn it
into a section and give it an ID of highlights so that we can can then scroll through it from our homepage that
way if we click buy later on we'll be able to see the Highlight section now let's also give a class name
to this section of w- screen which will give it a full width let's give it an overflow of hidden so we don't see any
scroll bars h- full for full height common Dash padding for paddings and BG D zinc for this nice looking background
color it's very similar to this full black but just a bit different let's create another div right within this
section with a class name equal to screen Max width and within it let's create another div that will contain our
H1 so here we can create an H1 with an ID of title so we can soon enough add animated let's give it a class name
equal to section dashe heading and let's say get the highlights of course if you buy the iPhone you get
the Highlights so we cannot see it right here as right now if we check the section heading in the class names
you'll notice that we apply the opacity zero and translate y20 so it's actually hidden so to get it showing you know
what we need to do we can use the use Gap hook like this from react call it provide a callback function and an empty
array then we can say gap. 2 where we animate a title and we animate it to the opacity of one and a y of zero to
reset its position and of course we can import Gap from Gap now if we save this you can see how it
not only shows up but it also comes from the bottom to the top great now we can style this div within which we have this
H1 by giving it a class name of MB of 12 for margin bottom we can also give it a w- full items Das end and justify Dash
between this way we'll have the highlights on the left and something else on the right
especially on bigger devices what I'm referring to are these two little pieces of text on the final
website which is this watch the film as well as watch the event links so let's add those by creating a new div directly
below the H1 that div will have a class name equal to flex flex-wrap items Das end and a gap of
five directly within it we can render a P tag and this P tag will say watch the film and then we can give this P tag a
class name of link and right below the text still within the P tag we want to render an image this image will have a
source equal to watch IMG coming from utils with an ALT tag of Watch and a class name equal to margin left of
two now if we save this and go back to our current version of the application we cannot yet see it as we're not really
animating it in so what we can do is also run the Gap do2 this time we're going to go for the
do link class name and we're going to animate it to opacity of one y of zero and save once we do that you can see
watch the film here now directly below we're going to duplicate it and create another link that's going to say watch
the event and here we can say write IMG coming from utils and this will be right now it looks like it comes below the
highlights but we want it to appear on the right side so what we can do here look looking at this div it looks like
the items end and justify between properties haven't been implemented because it doesn't have the flex display
so we can say on medium devices and larger we can give it a flex display and this will make the links appear on the
right side but now pay close attention you can see that they all appear at the same time whereas on the Finish side you
can see how they slowly animate in one after another so to achieve that look and that animation we can give it first
of all a duration of one to increase it a bit and then a stagger of
0.25 stagger will ensure that they only stagger one after another all of which have the same class name or the same
selector in this case that link we have a link here and we have a link here so now if we go back you can see highlights
first then the film then the event great so with that in mind the top of the Highlight section is done but of
course now the fun part begins we can focus on the video carousell component something that you don't really see
often so to create it let's go below the speed tag and Below two more divs and create our own custom video Carousel
component by going to components saying video carousel do jsx run
RFC and then go back and render it right here video Carousel and self close it of course we have to import it at the top
by saying import video Carousel from slide Carousel now you can see it right
here I'm going to collapse it as we'll be doing it for mobile devices as well which means that we can now dive into
the video Carousel and start implementing it this one will be quite complex trust me we're doing quite a lot
of stuff here a lot of animations and a lot of different videos which we need to scroll through at the same time so let's
first wrap everything into an empty react fragment and then have a div right below this div will have a class name
equal to flex and items St Center immediately within it we want to map over all of our highlight slides by
saying highlights slides like this coming from do do/ constants so if you look into it you'll notice that this is
essentially an array of a couple of different objects each one of which has an ID a list of text elements such as
the chip the video and the video duration we'll use all of this information to display all of these
videos one by one and it's not just the video it also has text that we show alongside that video so we want to map
over those slides and then for each one we get a list also an index and then we
automatically return something when I say automatically return I mean just have parentheses here and not currently
braces that means immediate return for for each one we want to return a div and we want to close it that div will have a
key equal to list. ID and it will have an ID of slider within it we can have a
div which we need to close and it will have a class name equal to video- Carousel underscore
container and we can save it so now if we scroll down we we cannot see anything yet but if you type something within it
you can see test test test test which means that we are properly displaying four different
slides now where we have the ID of slider we also want to give it a class name equal to on small devices padding
right of 20 and usually padding right of 10 that's just going to provide some spacing so you don't see the other slide
while the first one is not completed within this div we can run another div and that div will have a class
name equal to w- full h- full Flex D Center rounded -3 XL overflow hidden as we don't want to see those ugly scroll
bars we'll animate it to slide over different ones and then BG of black now you can see this black rectangle where
the video will go so right within this div let's create a video tag that will have a source within it like this and
that Source will have the SRC property of list. video with a type equal to video/
MP4 and now we get our first video right here but of course a video cannot yet play we need to make it play
automatically so let's give a couple of properties to this video such as ID of video so we can later on target it plays
in line like this will be set to true we're going to also give it a preload class of
Auto muted and that's it for now now as you can notice it's not going to start playing yet that's because
we're want to play it using some animations more on that later but for now let's create the layout around each
one of these slides we're going to go below below this video and Below one more div and create one last div that
will make this slide this div will have a class name equal to Absolute because we want to absolutely position that text
on top of our video with a property of top 12 left Dash inside of square brackets
5% and the zindex of 10 within that div we're going to map over our list texts by saying list do
text lists. map where we get each individual text and for each one we automatically return a P tag with a key
equal to let's do text and it's going to display text you can see enter A7 Pro
gamechanging chip groundbreaking performance let's style it a bit by giving it a class name equal to on
medium devices text- to Exel usually text- excl and f- medium there we go this is how it looks like
it's going to be much better once we actually start playing the video too first I'll create some refs or
references to specific elements so we can keep track of the video we're on I'm going to start by saying
const video ref is equal to use ref coming from react and at the start it will be set to an
empty array I will repeat this two more times call the second one video span ref and the third one video div ref we'll
have to manipulate and play with a lot of these different elements now that we have these refs
let's also create a state for the video by saying use State snippet and call it video and set video and at the start it
will be equal to an object don't forget to import Ed state from react this video will have some
properties like is end at the start set to false start play at the start set to false as well right the first one is not
yet playing we have to figure out which one is playing so for each video we'll have to know when to trigger this and
when to turn it to true then we have the video ID at the start set to zero is last video will be
set to false at the start and then is playing at the start set to false we'll need answers to all of these questions
and periodically we'll have to switch it on or off now just so it's easier to work with these pieces of data we can
immediately destructure those values by saying const and then getting the is end is last video start Play video ID and is
playing which is equal to video we have essentially just extracted those values or destructured the values so we can
then use them without saying video dot video dot video dot great so now let's create a use effect so we can start
playing those videos this use effect is of course coming from react so we have to import it and it will be a callback
function and we of course need to have a dependency array we will recall this use effect whenever the video ID changes or
whenever the start Play variable changes so what will we do in this video well first we have to figure out where are we
in our video playing Journey so we can say const current progress is equal to zero and then we have to get the span
element of the currently playing video by saying let span is equal to video span
ref. current more on that later finally if we have that span of a specific video ID then we can start animating it here
we'll animate the progress of the video remember for what that is if I go to the
finished website and reload you can see how nicely this progresses for the entire video duration and then opens up
a new one so we'll do that soon but first let's just focus on getting the videos to play in the first place to do
that we can say let anim which is short for animation is equal to gap which is coming from Gap dot 2 where we get a
span and then the video ID of that span and then as the second parameter we provide all of the options as you know
options don't necessarily have to be just properties that we animate like opacity or Y or xais it can also be
specific functions like on update what will happen once the animation updates which is a callback function the second
one we can have is oncomplete what happens if the animation is complete in this case since we're
working with a much more complex animation we need to keep track of all of these
values but this animation specifically has something to do with the progress tracking which we're not doing yet so
we'll get back to this very soon for now let's create another use effect on top of this one and this use effect will
deal specifically with the playing of the video so it can be retried whenever the start Play Changes whenever the
video ID changes the is playing or the loaded data that loaded data is a new use State Property which we can create
right here use State snippet loaded data set load the data at the start equal to an empty array more
this soon so what are we going to do in this use effect well here we can say say
something like if loaded data do length is greater than three then if not is playing we can say
video. current video id. pause so if we came to the end and if we're no longer playing then pause it
else if his playing is true then if start Play is also true then then video. current video id. playay so we find a
specific video we want to trigger and we play it this by itself won't yet start our first video and that's because we
haven't yet given it any refs so moving right here below to our video we have to give it a couple more properties first
of all let's give it a ref equal to here we're going to have a cook function where we get the element
and we want to say video ref. current I is equal to element like this so we're finding a specific index
in the video refs array and setting it to this current video element then on Play We want to call a callback function
where we want to set video where we get previous video information so prev video and then based of that information we
automatically return so you have to do parenthesis and then curly braces the spread of the previous video
so dot dot dot prev to get everything we have there but this time we turn on the is playing to be equal to true so on
play we spread all the information about the video but we said the is playing the true I know this is getting a bit more
complicated so if you have already already gotten stuck or if something is not clear don't worry you can code it
with me if it doesn't work like it should at the end of this video Carousel portion I will also provide you with a
complete code for the video Carousel so even if something breaks during the process you still got to watch it learn
from it and then you can paste it have it working and then explore exactly what we're doing now that we have only the
video it's kind of hard to see when the next one should be playing or what's happening with the video duration so
what do you say that we also implement the jsx for this progression tracking and this button too which we can use to
pause it and then we can continue with getting the video to play so with that in mind we can scroll down go below here
where we're rendering text go all the way until the bottom and then here we want to create another div this div will
have a class name equal to relative Flex Center and a margin top of 10 to divide it a bit from the content above
within it we want to have another div that will have a class name equal to flex Das Center padding y of five
padding X of seven background gray of 300 backdrop of blur and rounded Dash full this will create this rectangle
pill like sh shape so we can track our progression within there we want to go video. current. map where we get each
video but we don't need to do anything with it so we can just call it underscore as it's usually the practice
and then you can also get the index for each one of these video refs we want to immediately return a span
element and that span element will have a key equal to the index and we also need to give it a ref this ref will also
be equal to a cack function where we get the element and then we set video div ref. current index is equal to element
so we're going through a couple of these and whenever we have a new video we add it to this video div ref array we also
want to give it a class name equal to margin X of two to create some margins W of three for width h of three for height
you can see how the pill is changing shape BG gray of 200 there we go now we have four of these different dots
rounded Das full relative cursor Dash pointer within each one of these we want to create another
span element that span will have a class name equal to Absolute so it will be
absolutely positioned h- full for full height w- full for full width and rounded Das full to this one we also
want to give a similar ref as to the above one so we can simply paste the ref and change it from video div ref to
video span ref and we can self close this span right here there we go that should look
something like this wonderful and finally let's create the button to pause or reset it like we have it right
here while it's playing you can pause it and else if it's done you can reset the progress so going below this pan and
Below one more div we can create a button that will have a class name equal to
control- BTN you can see the button appear right here we can render an image and IMG tag right within it with a
source equal to if is last video then we render the replay IMG coming from utils else if it's not playing so if not is
playing then we render the play image else we render the pause image so we're using a double Turner right here for the
alt property we can check if it's the last video then we say replay else if it's not is playing then we say play
else we say pause so this little button has three different functionalities play pause and
replay and let's give it a Click by saying on click we want to check if it is the last video then we can call a
callback function which we will call handle process and pass it a string of video
reset this will temporarily break our application but don't worry about that then if it's not is playing like this we
can then call another callback function calling the same handled process function but this time with a play
action and for the last time we're going to call the same handle process but this time with the pause action so now you
might be wondering what is this special handle process function and from where will we import it well this is a
function which you will create so let's scroll up right here and let's create it right below this use effect by saying
const handled process which accepts the type of the action we want to make in the index and we're going to open up a
switch case so I like to use a switch whenever there's multiple cases sot switch based off of the type of the
action and if the case is video end in that case we're going to set video state by getting the previous video
State spreading it out by saying do do dot previous video is end whe set to true and we're
going to increment the video ID by by setting it to I + 1 looks like I missed a closing Arrow
right here there we go now we're good so this is if we're at the video end and don't forget the break the second case
is the video last so if we're the last video but not yet end here we also want to call set
video and we're going to also get the previous video which I guess we can shorten for just pre
previous video right here pre and then we want to immediately return something by first spreading the previous video
and then adding the is last video to true because it's the last one of course don't forget to break
it let's add another case which will be video reset where we can also basically duplicate this set video and instead of
saying is last video we will say is last video is false and we're going to reset the video ID to
zero let's break it and finally and most importantly we have a case of play so we want to play the video and here we can
again duplicate this set video paste it below and say is playing will be the opposite of previous that is
playing and that's basically the only thing we want to do we want to break it and at the end default we can return
the video so here we handled all of the different actions that we could ever do with that video that is great but still
not a lot is happening in the screen right right so let's use Gap to bring it all to action right at the top after we
destructure everything from our video we can use the used Gap hook like this coming from Gap react where we provide a
callback function and here in the dependency array we're going to add the is end and the video ID so that we
update stuff whenever the video ID changes here we want to animate the video to play when it is in the view by
saying gap. 2 we're going to select it by the ID of video and we want to provide it a couple of things first
we're going to provide it a scroll trigger like this so once this thing is in view then we trigger it once what is
in view well the video ID what do we do then well toggle actions so do something and we're going to say restart the video
this is when it first comes into the view and there are many different cases when it comes to the view from the top
or from the bottom in other cases for now we're going to say none none none we're only interested in making it play
once it first comes into view after the scroll trigger once we're complete with the video we want to have a callback
function and we want to set video to be equal to where we get the previous one immediate return do do dot pre by
spreading the previous state start Play will be set to true and is playing will also be set the
true now if we save this this by itself won't yet start playing the video which is fine but what will is the use of our
loaded data so the reason why we have this loaded data is because here in the original use effect we are checking if
the loaded data exists and only if it does only then do we start playing so what we have to do is create a new
function right here const handle loaded metadata equal to and this function will accept the index as well as the event we
pass into it and and it will simply call the set loaded data it will take all the previously loaded data so
pre and it will automatically return an array do do dot pre and then the new event we have added with this handle
loaded metadata we can now attach it to our video player so going to the video we can say
unloaded metadata and basically what this means means is this will get triggered with the event once the
metadata of the video has loaded so once it got the data we get that event and we call the handle loaded metadata and pass
the index as well as the event this Handler will call this function which will in return call our state Setter and
once it's in there this use effect will trigger the video play so let's save it and
reload and as you can see the video is now playing let's check that out one more time on full screen so if we go
here on full screen you can also see the videos which will soon play so let's reload and there we go the video starts
playing but nothing is happening with the animation here and once it ends we're not seeing the next video so let's
make that happen as well and once again if if you reach this point and if you're watching this and if this part is very
confusing don't worry about it at the end of this entire segment I'll provide you with the entire video Carousel code
so you'll be able to continue having the complete working code but still you will have learned a bit about how setting up
more complex video animations works now that we've got our first video playing let's also implement the way to track
the progress of that video we can do that right here I believe we even added a comment for ourselves there we go
animate the progress of the video so here we can say cons progress is equal to and we can use the math. seal method
and then get the anim do progress so this is directly built into gap which allows you to get the progress of the
animation how cool is that and then you can multiply that that by 100 to get the percent we can say if progress is not
equal to current progress then we want to update it by saying current progress is equal to
progress and of course this current progress has to be a let and then we use a gap. 2
functionality where we target a specific video div ref which is the container for this dot which will soon turn into a
progress Handler dot current of the specific video ID and then we're going to modify its width by saying width is
window. inner width is lower than 760 if that is the case then we're going
to make it something like 10 VW for mobile else if window. inner width is lower than
1,200 then we're going to make it something like 10 VW that's for tablet and else for laptop
we're going to make it for VW so if we do this you can immediately notice how it expands which is great but
still we have to animate the progress bar so let's go below and say gap. 2 span of that specific video ID we're
going to modify the width and we're going to do it dynamically by setting it to current
progress and then percent like this and we're going to change the background color to white so if we now save it you
can see how nicely if you reload it animates and moves further of course now it only lasts for the duration of the
animation which is a couple of seconds but now we want to actually modify the duration to be exactly as the duration
of the video so let's navigate to our oncomplete and check if is playing in that case we want to say gap. 2 video
div ref. current video ID we're going to modify the width to 12 pixels so only if it's playing its 12
usually it's going to be just a DOT so on complete we bring it back to a DOT and also gp. two we're now targeting
the span of a specific video ID like this we're going to change the background color to be equal to Hash AF
AF AF of course we must not end this right here we must end it right here below so if we now save it you can see
how quickly it starts and then gets back let's go below this on complete so that's going to be all the way here and
also exit this animation so exit curly brace and parentheses here want to say if video ID is equal to zero then we
want to restart the animation by saying anim do restart so this is a utility Handler
given by gsap and finally now we want to modify how long the animation lasts by saying
const anim update which is going to be used to update the progress bar here we can say anim
progress and bear with me we'll have to do some math we have to get the video. current video ID divided by
highlights slides video ID do video
duration so we divide those two times and that should give us the progress then we go down and say if is playing
then gap. ticker and ticker is used to update the progress bar do add anim update else if it's not playing gap.
tier. remove anim update and this anim update is coming from here but it needs to be one scope below so we
can actually access it there but here we cannot access the anim as I can see so we have to move all of this a bit to the
top right here so there's one closing here and then we have these two so now if I save it you can notice how it
expands and it's immediately all white and it stays that way of course this is still not the the same as on the
finished website where it slowly does it and then moves on to the next one so let's fix it one thing we have to do is
we have to give this video a few more Properties or rather a few more handlers we have to know when will it end so we
can say onended we're going to open up another callback function and we're going to check if the
index is not equal to three well in that case it's not yet the video end so we can call a Turner operator and call the
handle process where we pass the video end and then a specific index so we know which
one will we end and if we are at the third one we call the handle process and call it a video last so we know that we
need to restart in this case this can be an immediate return so we don't need curent
cly braces here at all and of course we don't need three equal signs if it's inequality if we save it now we should
be much closer to actually transitioning to the second bar which you can see it actually opens and it should go to the
third one as well but the videos are not yet reflecting that so let's go back to our animations right here to use
Gap that is here at the top and we're going to add a second Gap animation by saying gap. 2 and here we want to Target
the slider I believe we have given it an ID of slider yes you can see right here and we will modify it like this we will
apply a transform property where we will use the translate X and then we're going to make this a
dynamic template string and we're going to move it by minus 100 times the video ID so for each video the
first one is going to be zero so it's going to stay there for the second one it's going to be 1 two 3 and as we
update this video ID we're going to modify the percentage of how much we move away so that way new videos will
start showing up and of course we have to properly close it if we save this we're getting closer
but not there yet we can also modify the duration to two seconds and save it and reload we get the first video playing
it's looking good the second one but still nothing happens in this case we want to use a special ease function and
what are these ease functions well ease functions allow you to specify how you want your animation to happen it can
happen faster at the start and then slower at the end or you can give it some power at the start you can also
make it elastic like this you can play with it and do whatever you want quite interesting right in this case I found
the power two do inout to work the best with our video specifically great we're getting very very close to having all of
this working and I think I know why these are not getting properly cleared if we
scroll down all the way to where we're updating the specific animation here we are dividing
just the video ref with the video duration doesn't make too much sense what I wanted to do instead is get the
current time of the video and then divide that by the video duration only like that it will actually be able to
know how far did we come so if I reload now you'll be able to see that our video tracking progress update are now working
properly they go one to another and soon we'll be able to stop them as well and the reason why we're not moving from one
video to another right now believe it or not it's a simple typo instead of saying percent and then closing the parentheses
right here I first closed it and then added a percent sign so if we just modify these to and the reload the
screen we get the first video playing the progress works and then it still fails because I have an extra curly
brace so if I remove that extra curly brace now it works as you can see it goes to the last one it allows us to
reload or restart from scratch goes first second the pause doesn't work right now so let's fix it we are pausing
within our handle process where we have the play but I don't see the pause right here so basically we have to copy this
play and I think just renaming it to pause should do the trick because we're doing the toggle right
here is playing or is not playing so if we reload so if I click pause it works and I continue this looks
and feels wonderful it's not just the videos that make it special it's the pieces of text it's the
progress bar loading and this button right here one last thing we can do is I noticed that for some videos we need to
apply a specific class name right here so we can say class name to the video where we open up a dynamic block
of code and say if list. ID is equal to two then we can translate
x44 and close it and we don't need the other so we can just do the end end we can close it and then we can also say
pointer events none like this there we go if we now save it this looks great and as I promised if this is still not
working for you the full video Carousel will be added to that read me so you can copy it and override this code right
here if it didn't work before then it definitely will work now so with that in mind let's expand it to admire it in its
full Glory I'm going to scroll all the way to the top to check out our hero and now I'm going to bring the videos in
view it nicely opens up we get the second video playing too we can pause it we can play it it's going to go to the
third one and finally we can also restart start how cool is this I know I know
this was a more complicated one quite a complicated component to implement 200 lines of complex Logic for
video refs getting the progress bar to working and more but you got it even though it might not have worked at the
start you understand at least a bit better of how you would approach something as complex as this and that
counts too so great job on completing the video Carousel and with it completing the highlights section of the
video I hope you're excited for what's to come because the next thing is going to be the 3D model look at those
Reflections look at the Quality you can change the color and don't forget you can change the size so let's go ahead
and implement the 3D model next using 3js oh and just so I don't forget if you didn't download it at the start we have
created a special 3js and GP guide specifically I'm referring to the GP part right here if what you have now
developed was a bit tough and complicated I strongly advise you to just go through the guide take it step
by step and take the base Concepts in so then everything else will start making so much more sense I have also included
some special tips and tricks in there so GP and animations will be simpler for you in the future great with that said
let's get back to the 3D model so to get started with our 3D model let's create a new page right here or a new section
called Model like this and of course we have to import it from somewhere so let's import the model from components
model and of course therefore we have to create it right here by creating a new component called model. jsx with our R
afce right within it now back on our Local Host 5173 we can see the model right here at the bottom which means
that we can get started with developing it we're going to start as we usually do by turning this div into a section and
we're going to give it a class name equal to Common Das padding which will apply some common padding on all the
sides we can also create a div that's going to have a class name equal to screen- max-width
and within it we can create an H1 that will have an ID equal to heading because we're going to animate it very soon and
it will have a class name equal to heading or rather section dashe heading 2 and it can say something like take a
closer look look at what you might be wondering well of course our model now we cannot get see this piece of text
right here and that's because we will animate it using Gap so in this case we can scroll all the way to the top of
this model and say use Gap coming from Gap react which we simply call like a callback function right here and we can
specify an empty dependency array right here we can simply say gap. 2 of course Gap needs to be coming
from Gap and we can Target The Heading as we're used to and then we can also create a
new object saying what we want to animate we want to make it come to the position of zero and bring the opacity
to be equal to one that way our header will be showing there we go take a closer look now we can scroll below this
H1 and create a div which will serve as the container for our model so let's create a new div that will have a class
name equal to flex flex-all as we want the elements to appear in a column items Das Center and margin top of five right
here within that div we can create another div that will have a class name equal to w-o for full width h-
75 which will look something like this for the height and you want to specify by 75 VH which means vertical height so
that's about 34s of the screen on medium devices we can increase that a bit by saying h-h and that's going to be 90 VH
like this overflow hidden so there's no scroll bars and relative like this now we cannot yet see anything in there but
we have created some space to present our model within so to create our model or to show it we have of course will
render another custom component so we can separate the logic of the model of showing that 3D model from this entire
section so what we can do is create a new component called model view djsx and for now we can simply call rafc within
it and now we can use that model view and render it as a self-closing model view component like this there's two
different iPhones that we want to show here there's going to be the small one and the big one as you can see right
here and we'll want to render both of them so for that reason what we can do is we can immediately create references
for each one so let's go to the top and let's create a new use State snippet and this one will be size set size like this
at the start equal to small so we need to be able to choose which one we currently want to look at and of course
we need to import use state from react then we also want to get all of the other model details for the small or
the big so we can create another used State snippet and say model set model and at the start it will be equal to an
object containing the title which can be something like iPhone 15 Pro in natural titanium we can also specify different
colors so we can do that an array of hash 8 f8 a81 like this we can also do something
like hash ffe 7B 9 I found those values to work the best and hash 6f 6 c64 just so we have some colors to
choose from and and we can also specify the image this one will be yellow image which is coming from the utils this is
just the default state which we'll be able to modify later on and of course this model has to start with a lowercase
M like this now there is still a bit of setup we have to do we have to set up camera control for the model view so we
have to specify camera controls as well which is interesting and we will do them like this cons camera control small will
be equal to use ref coming from react and we will duplicate that and create a camera control large we need to have a
separate camera ref for each one of these two models and of course we use the size to Simply say which one are we
currently viewing here we specify the model details these are the different colors
for different meshes which we will use within our 3D models and here we add the texture which we're going to use you can
see how it looks like here it's a JPEG but it doesn't allow me to currently view it but you can view it within your
just typical finder or file explorer so with that in mind we have created camera controls for this model
view and also we need to create another ref to keep track of the model to access its properties when animating so we can
do that by saying cons small is equal to use ref where we can say new 3. group like this so you're creating a
new group of threejs elements and this three of course has to be imported from somewhere so for the first time in this
video we have to install 3js let's do it by saying mpm install three as well as ADD react D3
SLR and add react D3 SL fiber these are utility helpers that make the use of the 3js library
easier for react applications so let's simply import this three coming from three we can do that
at the top by saying import everything as three from three there we go and we can duplicate this and also
create one for the large model another thing we'll have to keep track of and I know there's a lot of things to keep
track of so this is the camera control this right here is the actual models themselves and then we need to keep
track of the rotation value of each model by saying const we can say small rotation set small rotation is equal to
use State and at the start it's going to be set to zero and we can modify this as well and set
large rotation as well so large rotation and set large rotation we have to keep track of the values of both of these
models at all times so that if we rotate it we can see and know where it is go back bring it to zero and then show the
other one great so this was a bit of a setup I know but now we can can actually pass all of the important information to
our model view which will soon render that model so let's pass it the index this one will of course be one because
it's the first one to show let's give it a group ref which is going to be equal to small a gap type
of view one so this is the first one control ref for camera control of camera control small set rotation state is
going to be equal to set small rotation and finally we want to pass the item which will be equal to the model
this model is universal as it can be a big one and a small one depending on what we choose in the state and also we
want to change the size right here by tracking what we have in the state great now if we go back to our current
application we can still see just the model view nothing more so now let's duplicate this below and let's make it
work for our big one by saying index is 2 large vi2 camera control
large also set large rotation and then the model and the size can remain the same now we can see two
model views and soon enough we'll render those models but for now we first have to show the canvas
so going right here below we can render a canvas component coming from react 3 fiber and within it we can render the
view. port like this and this view also has to be imported from react 3 Dray viewport is a way to render multiple
views of a model in the same canvas doing this will allow us to animate that model now let's also make this canvas
full screen so we can give it a last name equal to w- fo and h- fo and we can also style it a bit by giving it a style
property that can be position is fixed top is zero bottom is zero left is zero and right is zero with an overflow
of hidden there we go so we're just resetting the positioning and later on we'll also need to get access to the
event source and you can do that by saying Event Source is equal to document. getet element by
ID and we're going to get the root right here this is useful when you want to interact with the model that you work
with now this temporarily broke our application so let's go to inspect and go to the console and you can see right
here it says unod type error document. getl elements is not a function this right here should have been get element
by ID as it can only be singular so now we are back into the game before we start working on these 3D models let's
also show some additional information such as the title colors and the sizes that way as soon as we show the model
we'll be able to play with it and modify it so going back right here we can go below the canvas and below one more div
and create another div this one will have a class name equal to margin X of Auto and
w-o right within it we can create another P tag that will say model. tile and immediately you can see
iPhone 15 Pro in natural titanium and we can also style it a bit by giving it a class name equal to text Dash
SM font d light text- Center and margin bottom of five there we go that's better let's also create a div below that P tag
and that div will have a class name equal to flex Das Center and right within that div we'll have a UL that
will have a class name equal to color- container So within here we want to map map over all of our colors so we can
open up a new Dynamic block and say models. map and then to get access to these models we're going to import them
from constants and you may be wondering what is this well it's nothing more than an array containing a couple of objects
where each one contains some colors different meshes and also the title that is it so we want to map over those
models and get each individual item and then also the index of that color we're
showing and for each one we want to automatically return An Li which is a list item with a key equal to I a class
name equal to w-6 h-6 round-- full and margin X off two
and then most importantly we want to give it a style property of background color will be set to item.
color zero so this will be coming directly from that object within the models
array and then we can also give it an onclick so once we do that we want to set the model like
this and set the model to be that specific selected model be that blue yellow or whatever ever other color and
we can immediately close this li like this if we save it and scroll down you can see these four different beautiful
colors appear right here and we can also add a cursor Das pointer so that the user knows that they can actually click
it there we go it's not just for the show let's also go below this ul and let's create buttons for managing the
size we can do that by saying button with a class name equal to size- BTN Das container and within it we can simply
open a dynamic block of code and say sizes. map where we can destructure the label and the value of each size and
then automatically return a span that will have a key equal to label and it will simply display play
the label as well of course the sizes have to be imported from the constants now you can
see 61 and 67 let's style it a bit further by giving it a class name equal to size- BTN that's much better and
let's also give it a style property equal to background color and here if the size is equal to the selected value
then it can be white else it will be transparent that way we'll know which one is currently selected and also the
color if the size is triple equal to the value then it will be black because it has the white background else it'll be
white so now we can see which one is currently selected and let's also add an onclick where we can call a callback
function and set size to be that specific value so now if we save it you should be able to click and move between
those two states as well as select different colors and immediately see that the title changes as well that is
amazing but of course that's nothing without the models which are the main star of the show so we have to scroll
all the way up and navigate into our model view and that way we'll be able to make our colors and sizes make changes
to the 3D models will display on the screen so first things first let's accept all of the props we're passing
into this model view component we're going to get the index the group ref the Gap
type the control ref for the camera set rotation size the size and the item then we want to create a viewport for the
model by wrapping everything in a view coming from react 3 Dre each view has to have an index so we know which one it is
and we can pass it from the props the first one will have an index of zero and the second one of one we can also give
it an ID which will be a gep type also coming from props and let's also style our view a bit by giving it a class name
and just so we can initially see it I'm going to give it a border of two and border of red five 100 so now you can
see where it is positioned right now it is just a line in 2D but if I give it a w full and h- full it will take the full
height of the screen also we need to hide it if we're not showing it currently so we can turn this into a
dynamic template string like this and properly close it and only if index is equal to two then we want to
say right dash minus 100% that's going to look like this else nothing so this way we can
swap between the left and the right one next we want to play with the lighting a bit and the first source of light will
be the ambient light which lights up all the objects in the scene equally so we can say ambient light and we can get
give it an intensity of about 0.3 and right now it looks like it cannot properly read the light unknown
property intensity found but we'll fix that soon enough let's focus on what matters maybe even more than light well
who knows because we cannot have a camera without light right but still we need both the camera and the light to
get the picture so we'll use a type of camera that simulates the perspective of the human eye
and that is called the perspective camera coming from react 3 Dre like this we can give it a make default so
this is the default camera and give it a position that is an array of 0 04 so now we have the camera but it's still dark
we can then create some more custom lights by creating a new component called lights. jsx and from the read me
of this project you can copy the light jsx component and paste it right here you'll soon be able to notice that
this contains the environment and a couple of different lights we're using the reason why I
decided to provide these lights to you is because I was playing a lot with figuring out how to make this look the
best and with these light formers I managed to create custom lighting that are properly light up our 3D scene with
different lighting intensities positions and more and once again just to remind you more details on
these light formers custom lighting and 3D modeling with 3js in general you can find in the guide so with that in mind
it looks like that even though we have imported these lights right here still our 3js has some trouble figuring out
whether they actually work or not and this could be just an eslin issue so let's go back right here and let's call
our lights property like this by importing those lights at the top by saying import lights coming from slash
lights and if we scroll down it's still quite dark out there but don't worry as we'll figure it out soon right below the
lights I'm going to call a suspense which is used to provide some kind of a loader until the model loads like this
so you you can give it a fullback and then within the fullback you can define something that's going to load like
maybe a div that's going to say loading later on we'll make a custom loader but for now this will be good enough the
most important thing is now rendering the iPhone model now the way we can get to that iPhone is by checking out our
public models and then we have our scene. glb which contains the iPhone model now I have found found a
phenomenal GitHub repo that turns gtfs into jsx components so just click this link in the description and then simply
drag and drop your scene by revealing it in finder or opening in Explorer and then simply drag and drop it
in what it will do is it will automatically render it for you in the browser so you can check it out which is
very very cool for testing out different models but then you and more importantly what we care about is that it generated
an entire 3D jsx file with all of the meshes right here so let's simply copy that entire thing I think we can do it
somewhere here now here we can play with the model even more and modify the Shadows the types and stuff like that
but in this case I will just keep it as it is and import this entire thing copy it and I want to create a new
component called iphone. jsx and simply paste everything I have here don't worry about these eslint warnings for now with
that in mind let's go back to our code and right here within the suspense let's render this iPhone
model which of course has to be imported at the top by importing iPhone from iPhone
which will broke the screen because if you go into that iPhone you will see that right now it just exports it as a
function instead of saying something like function model and then at the bottom we can say export
default model that way we have something to import within our application and of course since it doesn't know where we
put this scene we have to say that it's coming from models scene. glb and if you scroll up in this same file you'll be
able to see that here we also have to say models scene glb if you do that our app is back to the working State and if
we scroll down you can see a very very tiny iPhone model in the middle I'm going to zoom it in and you can barely
see it so now let's actually play with the lights the positioning the camera and let's make it bigger I'm going to go
back to our model view right here close everything else so we can just focus on it but before that very quickly let's
get rid of these es lint warnings they're okay in this one but under lights they are quite ugly to look at
and especially within our iPhone model here they're all over the place so to fix it you can go into the eslint RC and
right here you can add a plugin called at react D3 and save it that way es Lin will
automatically know that these are real properties that exist and that you can call as you can see now it knows exactly
what intensity is and it's no longer complaining while we're here let's also remove this ugly border and let's make
this iPhone model the star of our show I'm going to wrap this entire suspense into something known as has orbit
controls which allow us to move the camera using the mouse so I'm going to say orbit controls coming from react 3
Dre and that will be a self-closing component right here so we don't yet have to wrap it but we do have to wrap
suspense within something known as a group so a group containing the suspense and the iPhone like
this this group will have a ref equal to group ref it will have a name if the
index like this is equal to one then it's small else it's going to be large and we can also give it a position which
is equal to an array of 0 0 0 to position the model in the center of the screen now let's play a bit with orbit
controls we want to make our orbit controls the default way of traversing over our model we want to give it a ref
equal to control ref we also want to give it enable Zoom to false as we don't want to zoom it in we just want to move
it around we're going to also disable panning so we cannot once again kind of move it
around and we're going to modify the rotate speed to about 0.4 so that it's slow and
steady then we're going to provide a Target to Target the center of the screen by saying new three and this
three has to be imported at the top by saying import everything as
three from three like this and now if we scroll down we want
to call it and construct a new Vector like this Vector 3 and give it 0 0 0 as x y and z a
so we position that in the center as well finally once we stop rotating we want to get the angle of the camera so
that we know where we are so we can say on end we can call a function that's going to set rotation
angle or rather set rotation State I think we called it to control ref do current dot get
aimal like this it's a weird one I know but we need to get this specific angle to know where we are in the space and
soon enough we'll be able to rotate our iPhone but for now let's scale it up so we can actually see it we can do that by
giving it a scale property and saying if index is triple equal to 1 then we want to say 15 15 15 else if it's the big one
we want to show we're going to make it 17 17 17 there we go that's more like it and you
can see that the orbit controls work because if we remove the orbit controls or if we comment them out you cannot
move it it stays stuck in place so these definitely come in handy and allow you to move the
model now we can also provide the item which contains all the information about that model and the size which also
contains the information about the size so this is our model as you can see we have it here and if you click here it
doesn't quite yet change the color but it will soon if we dive into it and create something known as a texture by
saying const texture is equal to use texture coming from react 3 Dre and we want to pass it props do item. image IMG
like this this contains the mesh we want to cover our phone with then we can use a use effect like
this and we're only going to call this when the material materials or the props that item change so once we make some
kind of a modification to these buttons that change the colors and the size within here we want to call the object
dot entries to get the key and the value pairs of all of our materials and we want to map over each one of these
materials where we get an individual material and then we check if that material exists we can check that by
checking if material zero is triple equal to a specific string that we can then compare with a specific color now
these are basically strings of IDs that contain about 10 to 15 characters and I definitely don't want you to type all of
these by yourself so in the read me down below you can find those five or six different material
colors as a matter of fact you can find the entire use effect belonging to the iPhone model so copy it and paste it
right here as you can see these are the material names that can be changed and they modify the color so material 1.
color is the new color coming from the props which we choose on the screen now we get an error because we didn't import
import use effect from react and we also need to import three so we can do that by saying import everything as three
coming from three and if we save that now we're back and would you look at that we have a yellow iPhone and it
actually looks quite good there we go we can change it to White and now our picker works as well this is wonderful
but we're going to make it even better if we go to the finished website you can see that on the blue iPhone we have a
very Vivid blue color if we change it to Yellow it is completely yellow and completely dark whereas on ours
currently yeah sure it does change a bit but for a white color it just looks too white right so what are we going to do
is take the texture from this image and then apply it to this specific front portion of the screen and the way I
found it is I use that same app that generated this jsx and then there I inspected to see which specific material
do I have to apply that texture to and you can use a control or command F and search for EI IU and find it here you
want to expand this mesh and then within it give it a mesh standard material with a
roughness of one and a map of texture that way we can apply black for black this one for the
white this one for the yellow blue and so on so you can see that now it makes complete sense and it looks much better
as we're applying a custom texture for each color great so with that in mind we can exit this iPhone and we can finalize
our model view by providing a proper loading because now if I reload this loading doesn't look too good so instead
let's create a new component called loader. jsx run rafc and then import it right here as a
custom component there we go and of course we have to import it at the top by saying
that that it's coming from loader loader now if we go to the loader now if we reload it will break because don't
forget we have to wrap it in HTML so that it knows that it's not 3D so we need to wrap it in
HTML and this HTML coming from react 3 Dre and then we can give it a div which we can absolutely position by giving it
a class name of absolute top zero left zero W full h- full Flex justify Das Center and items Das
Center within it we can render a new div that will say something like loading dot dot dot and we can also style this a bit
by giving it a class name of w-10 VW h-10 VW and rounded Dash full now if I scroll down and reload
it's looking just a tiny bit better but actually I created this loader file to give you the opportunity to play with
some interesting and exciting models maybe search the internet for some exciting 3D models of different loaders
and once again a complete list of websites where you can find different 3D models can be found in our 3js guide so
download it check it out and do something interesting with this model and once you do that go on
LinkedIn and x and tag us on there because I would be more than happy to share your work with that in mind you
can see that there's only one property that we didn't use which is the set rotation size and that's because I
misspelled it it was supposed to be set rotation state which we are using right here Below on end we properly set the
rotation state so with that in mind let's go back to our that's going to be a model. jsx and right now we have some
fixes to make you can see that our second model which is the big one is also visible on the bottom and if I
click right here nothing really happens right so let's play with gap where for the first time ever we're combining Gap
animations with 3js models to make something truly exciting like this thing right here where it rotates and we get
the second model to make that happen we can scroll all the way to the top create something known as a timeline we can
call it TL for short and call it a gap. timeline so that we can move across that timeline then we want to create a use
effect like this and it's only going to change when the size changes here we want to check
if we are going to trigger the size is equal to large in which case we're going to do something or if size is triple
equal to small when we can do something else so now we're going to do a special kind of Animation which is a timeline
animation so it looks like this broke our application most likely because we haven't yet imported use effect from
react yep that was it and now let's create a bit of a more complicated animation since it will be a bit more
complicated what do you say that we extracted logic to another file we can create a new file within the utils
folder which we can call animations.js within here we can say export const animate with gap
timeline and this is a special function which we will call now let's first talk a bit about what a timeline even is a
timeline is a powerful sequencing tool that acts as a container for tween and other timelines making it simple to
control them as a whole and precisely manage their timing without timelines building complex sequences would be far
more cumbersome because you need to use a delay for every animation like this you apply delays weight and so on but
with the timeline you can specify exactly what you want one after another but to make that happen instead of
calling gap. 2 you first create a timeline and then call the timeline. two exactly like what we have done right
here so what we can do next is we can call this animate with gsap timeline right here and of course we have to
import it from utils animations and we want to pass a couple of props to it we're going to pass the timeline itself
we're gonna pass the small model right here the small rotation as well as the view1 ID and the
view2 ID so we know when to move around and you might be wondering why are we doing small for the large one well if
the size is currently large we want to animate it to the small one and vice versa also we're going to give it an
object of transform where we're going to run a Translate X of minus
100% this will remove it from The View and we can also provide a duration of about 2 seconds so what we're doing
here is we get the current value of the small rotation then we rotate the small model by the value stored in that
rotation we animate the small model view to the left and we animate the large model view to the center but if the size
is small we're going to repeat the same thing right here but we're going to display the
large model and the large rotation and we're going to animate from V2 to vew one and the translate X is
going to be zero there we go so now we're passing all of the necessary props into this
animate with gap timeline and we can accept all those props right here first we passed in the timeline then the
rotation ref then the rotation State then the first Target then the second
target these are view1 and view2 and then all of the animation props now that we have these first we can call the
timeline do 2 and we want to go to rotation ref current. rotation so we get a specific rotation and we modify it by
saying Y is rotation State duration is 1 second and ease I found this one to work the best power
2.in out right below that one we call the timeline two once again and this time we timeline to the first Target and
we spread out all the animation props so these will be the things like why duration and more so animation props
coming from the props and we can provide the ease of power two. inout and also after that we can provide a string of
the lower than character this symbolizes to insert the animation at the start of the previous
animation finally we can duplicate this one right right here below and say timeline two second
target same thing and everything else will be the same so we animate from the first Target
to the second target now if we save this you can see that something started happening they're
moving so if we select the small one we get it back if we select the big one they're both gone now let's see why here
we have two and on the other one we have no models at all well we can go to our model and let's go directly into the
model view and here is where we're messing with which one are we showing so basically we modify the right position
of one to basically get it off of the screen but this right 100 is not going to work if it's not absolutely
positioned so here we can add position of absolute and now they show one on top of another look at this this is looking
a bit weird let me reload yeah there's still one on top of another and that's because this right is
not getting applied as it's outside of the dynamic block so it needs to be within that Dynamic block right here if
index is two then apply right else apply this one there we go so now it's hidden and if it go go right here it's showing
this is wonderful and you can see how nicely it rotates like if you mess with it it's going to rotate back to the
starting position and then move away this means that our models are now great we can modify the colors notice
how the screen also changes and you can go back to the different one that also changed the color the meshes the
textures the lighting it's all looking great and now that we can actually see the model we can also play with the
intensity a bit like bringing it to 0.5 maybe bring it to five there we go now you can notice a big difference or
even 10 right now everything is very very light no matter which color you choose so the colors really pop but to
get that a realistic look I kept it very very low to 0.3 and that way you can really see the titanium coming out of
this iPhone but of course this is something for you to play around with you can modify the perspective camera
the lights and so much more that's the beauty of 3js learning how to navigate your way around the 3D World and of
course if you want to learn a bit more about all of the different types of lights that exist all of the different
cameras that exist and all of the other properties that you can use to mess with your models definitely check out our
guide which is linked down below with that in mind let's close our model view animations and model and let's
expand our browser to full screen I'm going to scroll up and reload and let's see how all of this looks like in full
screen we have this beautiful titanium iPhone 15 Pro we scroll down this was a tough one right the Highlight section
with animated progress tracking bars this looks and feels good we can also pause it and we can scroll to reveal the
model now you can move it around see how it looks like in different light and make a decision on which one you want to
buy it's no longer should I buy it or not it's which color and which size should I get Apple's marketing division
is definitely very good so we can learn a lot from the way that they present their products on the website and this
is one of the perfect use cases for for smooth animations as we saw with the videos and also perfect use case for
showing up those 3D models there aren't a lot of 3D websites but if there is one that really should use 3D it's the one
where you can show the products in all of their full glory and now that you have done all of this created a 3D model
as well as these playing videos and a nice looking header when building websites as phenomenal as these ones
right here there's something that we often Overlook and that is performance right
you're going to say why should I care about performance when my websites look like this that's the most common thing
we think about as developers right but still no matter what you put into it they still have to be performant and
quick not to mention that the design should never take away from the form you need to be able to figure out if the
business objectives of the website are properly achieved such as is this titanium iPhone taking away from the
screen and are people actually clicking the buy button so today I wanted to take this video a step further and allow you
to get answers to all of those questions and learning this matters it matters a lot let me give you a comparison of two
rumes featuring projects from different developers take a moment to read through them and let me know which one sounds
more impressive the first one just built a website that looks like the iPhone 15 Pro page from Apple and used react 3js
and GAP cool right but the second developer developed that website as well as tracked the number of visitors and
how they're actually browsing the site are they taking the necessary actions that we want them to take the second
developer they're also tracking performance loading speeds clickthrough rates and all of of that good stuff so
let's be real which developer will get a job well it's going to be the one with business metrics and performance
optimizations so for that reason in this video even though you might not have expected it I want to teach you not just
how to build and deploy a website rather teach you how to get answers to all of those hard questions and we'll do that
using a completely free tool called Sentry which will give us access to all of this information and more it's super
simple to integrate so click the special link in the description so you can follow along and see exactly what I'm
seeing and then click try Sentry for free create your account by signing up with Google or GitHub and after you sign
up you'll be able to answer a couple of questions such as your organization's name if you have a company or if you
work within a company enter their name if not simply type JSM click I agree to terms in services and you can choose
whether you want to get email updates let's continue and now let's follow the
onboarding we can install Sentry by clicking start and we'll choose the platform we want to monitor in this case
it will be browser and how handy it is they also have a react wrapper press configure SDK and we can follow the
steps provided right here let me Zoom it in a bit and first things first we want to install Sentry as a dependency
so let's copy this command open up a terminal paste it and press enter then we can configure our SDK by
copying this entire block of code and heading over to our main. jsx here is where we can paste what we copied the
setup for Sentry we'll modify it just a tiny bit by removing this root render as we already have that right here and
we're going to keep the most important stuff right here that we copied it seems like a lot but you can also just remove
the comments and then you'll be able to see that there's basically a couple of specific properties that we are applying
right here to customize the way that we want to track our application there we go this is it next
we have to upload our source Maps which allow us to track the traces for errors trust me you're going to be pretty
amazed at what this does so let's copy it let's install it as we have done that before and to verify we can render this
somewhere by returning this button here we get asked to install the Sentry wizard so let's press Y and you'll be
asked to select what you want to do we can choose yes or no in this case it says you're not within a GitHub
repository the wizard will create an update files do you want to continue anyway I'm going to select yes are you
using Sentry SAS or selfhosted we'll be using Sentry SAS do you already have a Sentry account
yes we have just created it before the wizard will verify that and you can select your Sentry project and choose
your framework I'm going to choose vit and just like that it's going to install the Sentry vit plugin without
you having to do anything it's going to ask you for using cicd tool to build your application
we're going to say yes and we're going to say yes continue that's it we have successfully
set up Sentry for our project now that that got installed let's modify our Integrations right here
right now we're using the browser tracing integration but we also want to add Sentry do
metrics. metric aggregator integration like this and we also want to add a Sentry do
react router V6 browser tracing integration to which we can pass an object and say use
effect is equal to react. use effect this way it just knows that we're using react and how use effects work finally
we want to update our app jsx to wrap the app with Sentry so let's navigate over to app we're going to import
everything as Sentry from ad Sentry for/ react and then we can simply wrap our app by
saying Sentry do with profiler and then we wrap the app we
have believe it or not that's it that's the entire setup so right now it says this snippet contains an intentional
error and can be used as a test to make sure that everything is working as expected so let's simply copy this
return and instead of returning this entire main let's try to Simply return that button that contains a method that
doesn't exist I'm going to save it and run our application by running mpm
runev and opening it on Local Host 5173 immediately you can see break the world so now now if you click view
sample error it's going to process that sample event and it will give us all the
information about the event that happened type error object object has no update
from interesting this one doesn't belong to our app but soon enough we'll configure
Sentry to start viewing real errors so let's break our app this break the world is actually a button which you can click
and and it contains a method that doesn't exist within our application so if you inspect it and go to the console
you can see if I make this the normal size that it's going to say unod reference error method does not exist is
not defined so we really are breaking the world so once you do that Sentry should have gotten that event and should
enable our account so now if we go to issues you can see that we have a reference error method does not exist is
not defined Sentry will automatically group similar events together into an issue so let's click got it and we can
go into it and see more information about that issue a pretty crazy thing about this is that you can see the
browser the operating system as well as so much more information about that user their IP address the URL and more we can
also Mark it as handled or not handled we can also see which function triggered it and we can see full breath cramps of
how this error came to be all within this Sentry interface and not within our application so imagine if you gave your
app to the users and if they noticed an error it will be almost impossible to debug they would send you screenshots
pieces of code and so much more but with this you know exactly what is happening and believe it or not you you can also
see a replay of what the user was doing when the error happened you can do that by going to replays and you might need
to wait a bit or reload to ensure that it actually shows up but check this out we have most dead clicks which means
clicks that don't do anything and I did click on that button four times we have rage clicks as well uh because I was
clicking on it and nothing was happening so I was raging a bit guilty as charged and then we do have a full recording of
the duration with everything that was happening let's click into it and check it out if I click play we can see the
entire screen of exactly what I was doing on the screen and when I clicked it as well as when the specific errors
were happening how crazy is that I was also messing with my desktop and mobile view so we can see that as well and you
can see exactly what's happening right here on the timeline pretty cool stuff but of course the most
important thing we're concerned with is the errors tab where you can click it see the exact event ID and see all the
information about the error that happened so that we can resolve it and to resolve this error we can also scroll
down a bit and see more information you can see that the session replay since now it has been rendered actually
appears right here within that specific error so you don't even have to go to replace and then we have the complete
BREC cramp of the error as we have seen before and everything about the user's device browser and more and if you
scroll a bit up you'll be able to see this resources and maybe Solutions I like how at least they are being
realistic with AI sometimes you might get lucky but again maybe not so what we can do is we can click view suggestion
and their AI will of course of course if you give it consent try to solve the error for you and hey it looks like
you've encountered a reference error in your JavaScript code which we did so to fix this issue you'll need to define the
method does not exist in your code by adding it right here and they give you some more tips for debugging it in this
case instead of actually declaring it we know that this is faulty code which we don't need so for now I'm going to
Simply remove it from here and that will fix the error so I'm going to say yes this was surprisingly
helpful now let's see if the error has truly been fixed by going back to our app and reloading the screen yes we have
our Titanium video we have our highlight section and we have our iPhone model right here looks
great but we're not here just to fix errors let's explore the performance tab for you it might say zero it does
take a minute or two to load uh but very quickly you should be able to see 100 here I mean our website is loading
incredibly fast we can see that the timing is incredibly low and we can also head over to web
vitals and we can see the largest contentful paint within 300 milliseconds which is good and you get more
information about everything that is happening on your app I mean how cool is this and how convenient it is to have
all of this in one place we can also go to resources where you can track exactly what your website is transferring over
to the devices of different clients the main jsx is the main thing we're transferring now as well as some assets
and images next let's scroll down a bit and check the Discover tab here you can discover different
trends for your application like we can bring it to the last hour and you can see exact actly when your users were
doing what which is quite exciting so here you can see that one user had an error and there was a transaction for
the other user then you can track and see exactly what they're doing from what browser family what device and so much
more it is all here as we have explored before and you can also see complete Network events for everything they were
doing on the site next let's check out the dashboard you can choose from different templates that you can use
like the front- end template which shows you the erroring URLs and web vitals or you can just check out the general one
so let's see the general and here you can see the number of Errors the number of issues the number of affected users
which is interesting the handled versus unhandled errors uh yeah you can see this one is now counted as handled
because we have fixed the error you can see the Errors By browser so you know where everything is failing overall user
misery is also a very interesting metric to to track I guess and I mean all of this is working so well for tracking
what's happening on your application now let me go back and let's see if I can get some more information from the
frontend template by adding it to my dashboard and here if I zoom out just a tiny bit you can see more information
about the overall LCP FCP layout shifts happening page load times and more so you can see the top five issues by
unique users URLs where the issues are happening and if you have any slow page navigations of course you can customize
this by adding more vids for duration throughput crash rates health and so much more even LCP by country which is
good to know if you have users from different countries so I hope you like this little intro to Sentry and how we
can use it within in our project now as we continue developing our project we'll be able to come back to it and see if it
has recognize some new errors or if our apps performance dropped as we introduce some new animations so we'll be able to
track it all in real time and you'll see me use Sentry in many more videos in the future I recently found out about it and
I'm going to use it for all of my apps including our official course platform here there's a lot of things that could
go wrong just due to the sheer amount of features we're implementing within this project people that have purchased the
ultimate nextjs course have access to this platform and we want to ensure that nothing goes wrong on the platform we
have a lot of custom stuff like custom code blocks which you can copy uh all the way to complete files complete
configurations hints images and a lot more stuff like these callouts right here so you don't forget stuff so if
you're watching this video for building a gap and 3js react application you're going to love what we do in the ultimate
next gs14 course so check it out and you'll be able to access it within our new platform and getting back to sentury
as I said you'll see me using their software in many of the upcoming videos and we're going to dive deeper into
things like profiling user feedback that allows your users to quickly add a bug report cron actions alerts and so so
much more while my goal is to teach you how to build beautiful websites with this I want to take you a step further
and also teach you how to make them make sense from a business as well as a marketing and maybe even performance
optimization side of things so with that in mind let's focus on the next section of the day which is going to be this one
where you can explore the full story of how iPhone gets made with this video and some new images appear youring and of
course if you continue scrolling down more text and then these images animate back in so with that in mind let's get
started working on the next section by pulling this to the side and adding the next section right here within our
app.jsx to get started with our next section we can create a new components within the components folder called
features. jsx we can run our afce right within it and then we can navigate over right here import it features coming
from features and that's an automatic import from that/ components forward slash features now if we go back to our
website you should be able to see features right here at the bottom which means that we can dive right into the
features and start implementing it first things first we're going to turn this into a section with a class name equal
to H4 full for full height and common Dash padding we're going to also give it a BG off zinc as well as relative and
overflow Das hidden now you can see features has its own space right here let's also create a
div right here with a class name equal to screen-
max-width within it we'll have a div with a class name equal to margin bottom of 12 n w-
full and right within it we're going to have an H1 which will have an ID equal to we can
do features uncore title so we know what it is and you know why we're adding it that is because we want to animate it
let's also give it a class name equal to section dashe heading and it can say something like explore the full story
dramatic as Apple usually likes to do it so now we can add that first animation if we scroll up and say use Gap coming
from Gap react now you know how we use the used gab before you provide a callback
function right here and then you also add a dependency array now in this case I want to teach you how to make this
just a bit more optimized and we want to use a dry principle of good code architecture which means don't repeat
yourself now whenever we use the used gap which you can see it's a couple of times so far typically we use gap. two
and then specify what we want to happen and in these cases we didn't have to use the scroll trigger but sometimes we did
so if you see scroll trigger we used it in the video carousel right here where we have this used gab gep 2 with the
trigger video and then toggle actions now every time that we want to use a specific scroll trigger we need to
repeat this part trigger is video toggle actions is restart non Nan and so on so wouldn't it be better if we extracted
this function call where we repeat some stuff to a new function within our animations.js file we already have this
animate with gsap timeline but right here above it we can create a new export con animate with gap which is equal to
we get the target which we want to animate the animation props such as you know opacity one and then also scroll
props and here we're going to call the basic gap. two property of course Gap has to be
imported from gap which Target do we animate well we already have it under Target and then what are the animation
props such as opacity one right in this case we can just spread all of the animation props coming from the props
and then we can also add this scroll trigger that I talked about where the trigger will always be equal to the
Target in our case at least and then we also have these so-called toggle actions and what toggle actions are is they
determined how the length animation is controlled at four different places on enter so when we first enter it we want
to restart the animation then on leave once we leave this specific Target then we want to reverse the animation so this
is interesting reverse then when we enter back to it we want to restart and then when we leave back we want to do
reverse so this toggle action figures out what will happen with this specific animation on four different distinct
places whenever we scroll in when we come back when we scroll down and scroll up once again within here we can also
Define the starting position of the scroll trigger something like top 85% that means that when the top of the
trigger is 85% from the top of the viewport it's going to activate giving us enough space and time to trigger the
animation and we can also spread the rest of the scroll props great so now we have this animate with GP function with
scroll triggers and now we can go back not here but rather in the features and call animate with
gap and the only thing we have to do right now is provide the Target and in this case the title is the ID of the H1
so features uncore title and then we need to specify the Y is zero and opacity is one so basically we're simply
saying what do we want to animate and now if we scroll down we cannot see anything
yet and that's because I forgot to provide the hash to indicate that it's an ID so now if I reload oh nothing is
happening yet the ID seems to be correct and animate with gsap indeed provides
the gsap 2 functionality oh yeah but for scroll triggers to work we also need to register a scroll trigger plug-in and
you do that by importing the scroll trigger coming from gsap all and then you say gap. register
plugin and you simply pass that specific plugin you want to register this is how you use plugins within Gap so now if I
reload that is how you use plugins within Gap and the reason why we might not be able to see the animation yet is
because we cannot scroll to the top of it so we need to keep adding some more stuff so once we scroll down we'll be
able to see it so let's go back to Features below this H1 and Below another div we'll create a second div with a
class name equal to flex Flex Das call for column justify Das center items Das Center and overflow Dash hidden so we
don't see any scroll bars within it we can create another div which will help us position the title within it by
giving it a class name equal to margin top of 32 margin bottom of 24 and padding left of 242 within there we can
simply say H2 that is going to say iPhone and that iPhone you can see here so let's style it a bit by giving it a
class name equal to text- 5 XEL that's very big as well as on large devices text- 7 XEL which is even bigger and
font Das semi bolt there we go iPhone let's also duplicate this below and say forged in
titanium as here we want to show what it is made out of there we go iPhone forged in titanium and now you can also see the
explore the full story appear because we scrolled nicely there let's also go below this H2 and Below another div and
then create another div inside of which we'll show our animated videos and images let's give it a class name equal
to flex Das Center flex-all on small devices padding X of 10 then we can give it a div inside of
it which will help us position these elements by giving it a class name of relative
h-50 view height so that's 50% of the screen W full for full width flex and item stash
Center finally within here we want to display the video so we can say video with a
source that will have an SRC of explore video coming from utils and a type of video
MP4 if we scroll down we can see something that appears to be a non-playing video so let's give it a
property of plays in line let's give it an ID of explore video let's give it a class name of w-o
for full width h- full for full height object Das cover as well as object D Center we can also give it a preload of
none so it doesn't take away from the website's performance we will play it muted and we will Auto playay it and we
can also give it a ref to later on play with its settings so at the top we can create a new
ref const video ref is equal to use ref coming from react and we can pass that video ref right here and there we go as
you can see it started playing now what's going to happen when it ends it just stops but later on we want to make
sure that we animated it in and out once we go up and down before we do that let's also render the other two images
which we will animate so we can go below this video and Below another div and then create a container for our images
by saying div we'll have a class name equal to flex flex-all w- full and
relative within it we can create another div which will have a class name equal to feature Das video-
container and within it we can have another div that will contain one specific image so it will have a class
name equal to overflow Das hidden flex das1 and
h-50 VH within it we can render a self-closing image
tag that will have a source equal to explore one IMG an Al tag of something like titanium and a class name equal to
feature Das video Gore grow we'll use this to Target this
and give it some animations so now let's duplicate this entire div containing the image and let's make the second one
render the explore to IMG which we have to import say Titanium 2 and I think this is it if we save it and
reload we thought that we might be able to see the images but there's nothing yet and that's because they're hidden so
let's go ahead and animate them in we can scroll up and we can reuse this same animate with gap function where we can
provide a new Target of dot Gore grow and then we can expand it so it's easier to see which props are we passing and we
can also give it the animation props such as scale of one so it's going to get bigger opacity of one and ease of
power one so this is the way that it actually animates we can also give it some scroll properties and in this case
I'm going to use scrub of 5.5 I found this value to work the best and as soon as you save the file you can
see those two images appear they go out and they come back in wonderful now let's scroll a bit more
down and let's also add some text below those images so let's find the last image go
one two divs below and create a final div container that will have a class name equal to feature Das text-
container inside of it we can create another div that will have a class name equal to flex D1 and flex Das Center and
within it we can have a piece of text A P tag that has a class name equal
to feature Das text as well as Gore text because we'll animate it as well so this Gore stands for
Gap and here we can say iPhone 15 Pro is and then we can leave a space like so and save it you cannot see anything
yet because we didn't animate it in but at the end it should look something like this there we go iPhone
15 Pro is and then we want to create a span for the rest of the text so let's do that right below we can create a span
element with a class name equal to text- White and then you can follow along and type with me I'm going to say the first
iPhone to feature an AOS space grade
titanium design using the same aloy that
spacecrafts use for Missions to Mars okay let's go back we still cannot
see it so now might be a good idea to animate that in so if we right here below this animate with gap we can add a
new one and say animate with gap what do we want to animate in this case it will be a Gore text you see how easy it is
once you have a function you can reuse then you provide specific properties you want to animate such as y of zero
opacity of one we can also do an ease of power two. in out and a duration of one of course this has to be within an
object so let's fix it there we go and that is it so now if you reload you can see that the text
appears right below let's fix this it's an iPhone and now if I reload it's not there that's because we have to scroll a
bit more to see it don't worry we'll do that soon let's just go below this div and then duplicate this entire div with
flex one and flex center for the second piece of text there we go now we can see it but
of course we have to say something different now so in this case I will say something like let's do
titanium has one of the best strength to weight ratios of any metal making these are and here we can
say lightest Pro Models ever Apple surely does know how to Market and here we can
say you'll notice the difference the moment you pick one up there we go so now we have this nice
piece of text right here looking great so now this entire section is looking good the images are indeed animating in
the text comes in as well but this video once it continues playing it's just stuck so we have to play with it a bit
more to make it come to life let's scroll up and what do you say that we try using this animate with gap so we
can say animate with gap where we can provide the hash explore video and save it now if you reload it starts playing
it looks great there we go it animates but if you scroll up or down still nothing happens
so let's go to animate with gap let's copy this entire gap. 2 and for this one let's apply a manual animation without
using a reusable function because it will be just a bit different so the target will be the explore video of
course with the hash at the start we don't need to pass any animation props the scroll trigger will also be
explore video and the actions will be a bit different because we're dealing with the video so it's going to be play pause
if we go away and then reverse
restart you can play with these toggle actions a bit more and see how they behave finally the start will be minus
10% at the bottom and finally the third property will be uncomplete so what happens once it is
complete and here we want to say video. playay so essentially we will just restart the play and of course here we
also have to import Gap from Gap and now we can scroll down you can see that the video plays the images
animate and once it comes to the end if we go out and come back again nothing happens and that's because
this video. playay right here is not referring to anything rather it should be saying video
ref. current. playay because that's how we're targeting this video so now as you can see it's playing and once it
finishes if I scroll up or down it will start playing once again great now let's expand our browser and check this
out right here after here you see this great looking model you scroll down and you're greeted with explore the full
story of the iPhone forced in titanium we have this great looking video and two images that give you more detail now if
you scroll down you see some pieces of text and if you scroll up nothing happens to the video but if you go once
again down it starts playing again it's just a small little detail and of course you have a bit of creative freedom to
figure out how you want to play with these animations by choosing when you want to trigger them you can trigger
them on click or on scroll or in many different situations with that in mind our phenomenal feature section has now
been completed it's been a bit easier than the last two right well that's because now you know how to animate
better and let's be honest it also was a bit easier to implement than the last two but now let's move to the next one
which looks like this a 17 Pro chip a monster for gaming looks like this and on desktop devices it looks like this
the chip animates in and this great looking video starts playing so with that in mind let's start doing that
section next by going back to our development environment closing everything besides the app and creating
a new component within the components folder called how it works or you can also call it a chip so I'm going to say
how it works. jsx run RFC go back to the app and render the how it works section which of course we
have to import from the components how it works and now at the bottom there it is we can come into it and start
developing it to get started working on our how it works section we can can first turn it into a section and give it
a class name equal to Common padding as we typically do next we want to also give it a Max screen width so we can
create a new div and give it a class name equal to screen Max width now right within it we can create a new div that
will have an ID equal to Chip and yes this will be our processor chip image so we can give it a class name equal to
flex Das Center w- full and margin y of 20 within it we can render the self-closing image tag this image will
have a source equal to chip image or chip IMG coming from utils as well as an Al tag of Chip and a
width of about 180 and a height of about 180 as well there we go A7 Pro chip now what do you
say that we go ahead and animate it so right at the top we can use the use Gap hook and we can create a callback
function and then an empty dependency array right here we can say Gap Dot and for the first time ever we'll use the
from property instead of to property because we're animating it from a specific position so here we can say
what do we want to animate it's going to be the ID of Chip and we have to import Gap from Gap here we can give it some
scroll Properties by saying scroll trigger and the trigger will be the actual chip so once we reach it and
we're going to start on about 20% from the bottom and we want to animate from opacity of
zero scale of two duration of two as well and ease of
power two. inout now if we save it you can see it's gone and then it comes in as simple as
that let's reload that and see it one more time there we go that's looking great now let's go below the chip and
below the div and create another div with a class name equal to flex flex-all items D Center and right within
it we can create a new H2 property with a class name equal to hiw which means how it works title like this and we can
say something like let's do A7 Pro chip like this and then we can add a Break Tag and
then say a monster wi for gaming so now you can apparently game on your phone as well below it we want to
have a P tag with a class name equal to hiw subtitle and here we can say it's here
the biggest redesign in the history of apple gpus and say
there we go that's more like it now below it we want to show that huge video which will be playing right
here so let's scroll down let's go below the P tag and Below one more div and create a container for our video player
we can do that by saying div with a class name equal to margin top of 10 on medium devices margin top of 20 and a
margin bottom of 14 within it we can give it a div with a class name equal to
relative h- full for full height and a flex Das Center within it we can have one last div with a class name equal to
overflow Das hidden and within it we can render the image so this will be a self-closing
image with a source equal to frame IMG coming from utils an Al tag of frame and a class name equal to BG -
transparent relative and Z of 10 so now if we save it you can see this iPhone looking frame we want to place the video
right within it so right below this image we can have another div with a class name equal to hiw video
and right within it we can create a new video property with a source of SRC frame
video and a type of video MP4 now it appears at the bottom of it but let's style it a now currently it
appears at the bottom of it and that's because we should have put it below this div closing the image
so here we have the image and then we go one div down and then paste it right here now it fits perfectly within the
image let's also style this video property by giving it a class name equal to pointer-events
dnone let's give it a plays in line a preload of none a muted property Auto playay and we can also give it a ref
equal to video ref which we need to of course create at the top by saying const video ref is equal to use ref coming
from react which we of course have to import now if we save that you can see that the video starts autop playing of
course we'll kind of animate it so that it looks better even on larger devices now we want to add a bit of text at the
bottom so we can scroll below the video and then below one two more divs and here we want to do a P tag that says
honai star rail this is apparently a very good game that runs on this specific chip we can style it by giving
it a class name of text- gray font D semi bold text- Center and a margin top of three to divide it a bit
from the phone now right below it we want to have a couple of pieces of text that nicely slides in and this text is
quite similar to the text that we had in the previous section so let's go to the app go to features and let's just copy
these two pieces of text there we go div text container as a matter of fact we can copy the entire text container from
here to here and then paste it right within how it works below this P tag now now if we save it and go back
you won't be able to see it yet because it's hidden by default so let's style it a bit instead of saying feature text
container we can rename it to hiw which means how it works text container then it can have a property of flex flex das1
and in this case we can do justify Center and flex-all next instead of feature text we
can have an hiw text there we go and we can call it g fade in because we want to fade this text in and here we
can say something like A7 Pro is an entirely new class of iPhone chip that
delivers our space and then in white we can say something like best graphic performance by far we can delete this
thing after the span and then we have the second div which we can remove and just have a
P tag that says hiw text we can say something like mobile within the span games
will look and feel so immersive and then after the span we can say something like with incredibly
detailed environments and characters now if we save it you can see
this text right here but we cannot yet see this one that's because this one also has to say fade
in and then both will be gone and we'll be able to animate them once we scroll in before we do that let's also add this
one new proc class GPU with six course that's going to be below this div containing the P tag
it's going to be a special div with a class name equal to flex D1 Flex justify Das Center
flex-all and Gore fade in as well within it we can have a P tag that will say something like new and it will have a
class name equal to hiw text now we can duplicate this two more times the second one will say Pro class
GPU and the third one will say with six course now if I save it we cannot yet see it because it also will fade in in
the middle one will have a class name of big text because we want it to appear like this so now let's go ahead and fade
those in we can do that by scrolling up going below this Gap from and calling calling our reusable function animate
with gap we want to animate anything with a class of G fade in make sure to add a DOT at the start as it's a
class and then we can provide opacity of one y position of zero duration of one and ease of power 2.
inout if we save it you can see all of the nicely scroll in now it looks like this is not properly positioned so let's
position it properly if we scroll down you'll notice that we have this div closing the video and then one more div
which closes this video context and then below it we have the honai star rail but what needed to happen here is we need to
close this previous div so here we close another div and then right below the end we can remove one closing sign this will
now properly position it also looking at this part at the bottom it seems like it's too close to what we have at the
top so let's see if it's in the right container we have this hiw text container and it looks like I ended it a
bit too soon it should have been ended right here at the bottom so if I fix this now this looks better so let's
expand it to see it on full screen screen I'm going to scroll up and reload and now I'm going to smoothly scroll
down you see the chip animate you see this video play looks much better on the big screen and then we have the text
right here oh let's see if this text is looking good it looks like the positioning is a bit off as you can see
right here it looks like we didn't properly close these two first pieces of text
together so let's do that by taking a look at this one and then we have to close it right below the speed
tag now if we do that you can see it looks great we cannot get to the second piece
of text because we don't have the footer yet but we will soon and it will look like
this so with that in mind let's quickly get the footer going as well it will be quite simple we just
have to go to the components and create a new footer jsx component where we can run
RFC and we can just render this footer right here of course it has to be imported at the top footer coming from
footer there it is at the bottom left we can dive into it and we can develop it by enclosing it within an HTML 5 footer
property with a class name equal to padding y of five on small devices padding X of 10 and
usually padding X of five as well let's also bring this back to the mobile view so we can see what's
happening within this footer we can have another div for the max screen width by saying class name is equal to screen-
max-width within it we can have another div for our first part of the footer within it
we can have a P tag that will say more ways to shop there we go more ways to shop Let's
style it a bit by giving it a class name of font D semibold text- gray and text- Xs for extra small then within this
speed tag we can have a span that will have a class name equal to underline inex Das blue to signify
it's a link we can add a space beforehand and say find an Apple
store we can also add a space exit the span so that looks like this right now and this space can be outside so it
doesn't get an underline right here there we go and then out of the span we can say
or and then once again within this same span so we can simply copy it and paste it we can say other
retailer and then exit out of the span near you there we go so this looks good we need to provide some spacing so after
or and after the span some space we can go here and duplicate this P tag one more time right below the first one and
properly close it and here we can say something like or call and then we can do some kind of a
phone number I'm just going to type some random stuff right here there we go this looks good to me now we want to go below
the speed tag and below this div and create just a self-closing div which will act as a divider line by giving it
a class name of BG neutral of 700 margin y of five h-1 pixel and w- full this will give us a nice divider
line and right below it we can show all of the footer links so to do that we can just say div with a class name equal to
flex on medium devices flex-r Flex Das column on smaller devices on medium devices items Dash
Center and justify Dash between within it we can have a P tag that will have the same class name as
the one above so we can copy that class name font semi bold text Gray and text Xs and we can say something like
copyright 2024 Apple Incorporated All Rights
Reserved there we go and finally we can have a div below this P tag with a class name of flex and here we can map over
our footer links so footer links coming from constants map where we get each
individual link and for each one we can return a P tag with a key equal to link same class name once again as the
previous one and within it we can render a link and then a space after the link that will look like this and you have
all of the links right here now you can notice that after some we don't have space so we can say if I
is not equal to footer links do length minus one so if it's not the last one then also add a
span with a class name of margin X of two so MX2 and add a straight line like this and
this will create some spacing but of course make sure that you're properly closing everything and in this case we
also have to get the index as we're mapping over it and now if we scroll down you can see this great looking
footer and of course you can turn these into links once you actually have somewhere to navigate and with that said
our footer is done but it's not just the footer it's our entire entire Gap 3js and Sentry powered website and now is
the time that we deploy it it's time to share this wonderful looking hero section that animates in this highlight
section which we worked so hard on this great looking 3js model section as well as the explore the full story and
materials the chipset and even the footer it's time to get it all deployed and on the internet so you can share it
with everyone to start deploying our Apple website head over to your hostinger dashboard find the project and
head to its file manager now you can go into the public HTML and remove this default PHP by deleting it then we'll be
able to upload our entire code base so back within our Visual Studio code you can stop our terminal from running by
pressing contrl C and then clear it next head over over to package.json and within here we can see that the build
script is mpm run build so let's type mpm run build which will run an optimized
production build of our application there we go in about 8 seconds it is done so now if you close this up and
head to the file explorer if you collapse it you'll be able to see a new this folder appear which if you right
click you can reveal in finder or open in file explorer once you open it you can go into it copy all of the files and
simply drag and drop them within this empty folder on our H panel this should take just about a minute maybe even less
and as soon as it is done we can go back to our specific projects dashboard and click our chosen domain name just like
that our project is now deployed and live on the internet it took less than a minute now now we can scroll through it
and admire it in its full Glory with this phenomenal highlight section not to mention that we also have this great
looking Apple iPhone logo and the Apple iPhone title and our domain is https secured let's continue scrolling down a
bit to take a closer look at our 3D model this is looking phenomenal let's not forget that we can also change the
colors which are immediately reflected right here and let's see how Gap and 3js work together by animating this model
there we go that's more like it now let's continue and see this section where we can see this titanium in more
detail learn more about the a17 pro chip and then see the footer with all the links of course let's not forget that
the entire project is completely mobile responsive so if I open up my inspect element and collapse this just a bit you
can see how in Mobile we get a completely different view with the Highlight section videos appearing like
this 3D model looking like this and all of the other sections seamlessly fitting into the
view wonderful so with that in mind huge thanks to you for coming to the end of this video and congratulations be proud
of yourself that you buil something like this and if you liked what we were building
here you will love what we do on JS mastery. proo specifically our ultimate next gs14 course I can proudly say that
it is the best course out there to make you the top one nextjs developer we follow what the best companies in the
world are doing and how they're using nextjs they're not using it like good old react because then they would fall
into a trap off you using the client side on everything and having bad performance accessibility and SEO
thankfully I'm going to teach you how to use it like your real Pro we'll do a deep down to fully understand how it
works behind the scenes then we'll build and deploy a very complex app and you'll also get a chance to participate in
active lessons where we give you complete hints and then you have to build a specific feature everything from
task to examples think resources and even hints on developing something so you can truly understand what you're
doing and of course you're going to build one of the best apps out there a modern version of Stack
workflow so with that said what are you waiting for go to jm.pro and check out our ultimate next js14 course I'll see
you there are you finished building those basic websites that even AI tools like vzer can quickly spin up now is
your time to flex and build a modern landing page with smooth animations that stand out from other let's be honest
outdated and boring sites this is our top uiux video yet and probably the best one you'll find on YouTube let's take a
look at the final application you'll build to Future proof your skills presenting brainwave a modern AI app
you'll build a beautiful hero section with different shapes reacting to your cursor a Navar with a colorful button
that transforms into an animated hamburger menu when you're on smaller screens and look at that subtle smooth
scroll Parallax effect that moves these elements down as we scroll moving on we've got a nice Services section
featuring gradient borders on the cards and unique curved rectangle shapes each of these cards also reveals a hidden
background image next we have a pattern that showcases the most important elements in a circular layout after that
is a very fresh and modern web development layout called bento box many popular companies like apple linear and
clerk use this layout to display their features effectively below there's an always needed pricing section after that
there is a grid style layout presenting the application's road map with gradients grid lines high quality images
and geometry lines on both sides creating a modern look lastly there's a simple footer where we connect to the
website social media pages of course everything's 100% mobile responsive which makes this a perfect tutorial to
learn not just to Cod a design like this but also the best practices of responsive front-end development which
will save you hours and make you a front-end machine this is the best time to go beyond the basics and make
something cool and creative to show that you're at least one step ahead of AI tools and for that we have to thank our
friends over at ui8 their creativity made this special design possible this video features just a couple of screens
out of 44 pre-made screens and hundreds of components check them out the link is in the description deson and if you're
still wondering if you should learn how to build this trust me you really should JavaScript knowledge is required and I
highly recommend taking our Tailwind CSS crash course before watching this video the first step in building our app is
setting up our hosting I want to teach you how to deploy this incredible app to the Internet so everyone can see what
you've built see the app you'll buil today isn't just a project it's a career asset it's designed to Showcase
everything you're capable of making you an attractive candidate for any job I highly recommend Stinger for this app
they're offering an amazing deal right now I'll go for the business plan here's why it's perfect for this project you
get up to five times increased performance free SSL for https security which builds trust with anyone visiting
your website you also get a free domain name giving your website that professional touch and a free CDN to
speed up your site it ensures that your website loads quickly improving the user experience and because we've partnered
with hostinger you get an even bigger discount so click the special link in the description click claim deal and add
to card here we have to choose the period of our hosting and I'll choose 48 months to save the most down below you
can choose your payment method and enter your JavaScript Mastery coupon code which gives you the biggest available
discount on your hosting package and once you purchase we are ready to set everything up right within hostinger
guided setup it's asking us what tool we want to use WordPress with AI or the hosting your website builder in this
case we are real developers so we're going to click skip as we want to develop our own website and I love this
UI as you can see I'm using hostinger to host our official JS mastery. proo website there you can check out our
ultimate nextjs course or if you're a bit more advanced the JSM master class but for our brain wave let's try to
think of something unique I'll go with jsmb brainwave and in this case theom domain is available and it's completely
free for the first year let's click next and once your domain registers you'll also be able to choose where your
website target audience is so that way it loads fastest for them I'm going to leave it as the default and click next
and just like that our hosting has been set up now let's actually develop our application so that at the end of this
video we can deploy it using our new hosting and domain name to start developing our fantastic project we'll
start from bare Beginnings by creating a new empty folder on our desktop we can call it
brainwave and simply drag and drop it into your empty Visual Studio code once you have it open up your terminal and we
can get started first I'll teach you how to set up your react project using V and then we'll set up Tailwind CSS which
will allow us to style our applications much more easily so to get started you can head over to Tailwind css.com click
get started then go to quick search and type vit click install tailin CSS with vit and let's follow the steps first we
have to create our project so let's just copy this Command right here paste it within our
console but then instead of my project type do slash which will create this project setup within our current
repository press y to install create V CLI and then as you can see right here run mpm install to install all the
necessary dep dependencies and then run mpm runev to run our project on Local Host
5173 and there we go we are live with v and react now let's follow the second step in our guide which is to install
tailpin CSS so let's copy this command stop our terminal from running clear it and paste what you copied mpm install DD
tailin CSS postcss Auto prefixer and then later on after that MPX tailin CSS in it- P once you do that you'll see
some new files appear next let's follow the other steps as well such as configuring our template paths so copy
this content part and let's head over to tailin config.js that is right here and modify the content that way it will know
where to find tailin CSS class names next we have to add our tailin CSS directives so copy this head over to
Source index.css remove every everything from here and simply paste the Tailwind CSS directives
then as the application says run mpm randev one more time and let's make some changes to our
app.jsx such as by adding this H1 that says hello world so if we go right here we can remove what we have right now and
just replace everything with a simple H1 we can remove the count the logos and everything else that's in here the only
thing we need is the import of the app CSS and this hello world back on our Local Host 5173 you can see that it is
bolded and underlined which means that Tailwind CSS is properly reading our utility class names such as text 3 Excel
font bold and underline and it's applying specific CSS properties if this popup is not appearing for you telling
you exactly which CSS styles are getting applied that must mean that you don't have the Tailwind CSS extension so
simply type Tailwind under extensions and install Tailwind CSS intellisense with that in mind you've successfully
set up Tailwind CSS with your simple V project now let's focus on formatting a bit to ensure that our codebase is
always clean and readable you can create a new folder within the root of your application called vs code within there
create a new file called settings. Json doing this we're specifically applying some settings just
for this project in the workspace it won't work for all of your other projects this is very handy to use if
you have different settings for different projects you're working on and for this project specifically I have
created a configuration that uses prettier that my entire team and I use when creating these projects so you can
find it in the readme of this project copy it and then paste it right here it's going to apply some prettier
properties like tab width single quotes and more now if you go back to your app.jsx and if you modify something or
just press save you'll notice how automatically it will format it based on its properties this will ensure that you
and I always have the same exact code the next thing we'll do is create a file and folder structure to make it easier
to develop our application in the future so you can head over to source and delete the app.css as we won't need it
and remove it from app.jsx all of the Styles we'll use will be within the index.css next we'll
update our Tailwind doc config.js with the colors we'll be using throughout this project this file will also be in
the read me down below so simply copy it and then override what we have right here you can see right here that we're
adding some special class names such as H1s H2S and so on as well as we are adding some special font families and
colors that's more or less it this will be very helpful later on as we won't necessarily have to say use the color
ac6 AF rather we'll be able to declare it in a simpler way another special thing that we've done here is this
plugins part which you can see here this allows us to Define some of the components that we can then later on use
within our application such as the H1s we want all of our H1s to have same exact Styles which is why we apply these
specific properties to all of the components that use the H1 class names next we want to go inside of the
index.css and also in the read me you can find the updated file and override this one right here here we provide some
special class names for rotations for some animations we'll have but more or less we simply import and set the fonts
and another thing we can do here is declare the color scheme to be dark as most of our application will have dark
colors now if we go within our appli it's going to look something like this so now that our Base Class names are set
up we can start focusing on the file and folder structure but don't worry you will still write all of the Styles these
are only some baseline classes so what we can do next is open up our terminal and open up a new
terminal tab inside of which we can install react router Dom by running mpm install
react-router-dom then we can go to source and main. jsx and we can wrap our entire application with the router by
wrapping our app right here with the router which is coming from react router Dom like this we have to close it of
course and indent it properly which prettier will do for us which is great now it's not router right here that we
have to import rather it's the browser router as router coming from react router Dom great this is exactly what we
want next if you go to your browser you can notice how you have this default v logo we want to make this a real fabicon
corresponding to application UI such as this one brainwave to do that you can delete the existing assets folder within
the source folder and then in the read me down below you can find the assets folder
containing all of the images and icons we'll be using throughout this project so simply download it unzip it and then
drag and drop it here within the source folder and if you expand it you'll see a lot of different images all sorted
within their own sections you can also see that we have our brainwave SVG which is the actual icon we'll use for the
favicon great now we want to head over within our index.html and we can modify our link
icon from v.svg to something like SRC or slsrc SL assets SLB brainwave
symbol. SVG we can also modify the title to say brain wve if we save it and go back you can
see that our meta taags have modified now we have this brainwave icon as well as the brain wave title which means that
we are ready to start setting up our application skeleton meaning the structure for where all of the
components will go great job on setting up a react project using V Tailwind CSS formatting and the base file and folder
structure to get started creating our layout we can navigate over to our app.jsx which will be our homepage here
we can declare our app using the es6 plus const function like this and then we can wrap our H1 with something known
as a react fragment that looks like this so we have a react fragment allowing us to add more elements right here and of
course we have to close our return now below our H1 we'll render something known as a button gradient and to get
access to this button gradient we can say import button gradient from assets SL SVG for/ button gradient
like this this button gradient is an SVG through which we're giving the gradient effect to the button if you hold command
and navigate into this button gradient you'll see different linear gradients they are going to be used within buttons
we're giving an ID to each one of these linear gradients so we can then later on consume them within our code so what do
you say that we start off with a button component so I can show you how we're going to consume this button
gradient we can create a new component within a new folder called components and within components we can create a
new file called button. jsx within our button we can run rafc which will create a new react Arrow function if this
didn't work for you that must mean that you don't have the es7 react Redux react native Snippets installed so install it
and try again now we can import this button within our app.jsx just to test it out so let's put it within a
div and that div will have a class name equal to we can add a bit of a padding top so like PT Dash and let's do a
4.75 REM whenever you want to provide specific values then you can use square brackets we can also on large devices
provide a padding top off about let's do 5.25 RM and overflow of hidden within there we
can render our button component which we can automatically import from components button it won't
be a self-closing component we can give it a class name of mt10 for margin top and an hre off hash login and it can say
something for now now if you go back to our Local Host 5 73 you can see this simple button
right here but we cannot yet see something we just see hello world that something is hidden because the button
is just rendering the text that says button so what we must do now is transform this button into a completely
reusable component this is why I wanted to start off this project with a simple button because if you can understand how
to create complex reusable components on something as simple as a button then you can do it for more complex things as
well so let's get started by making this button accept some of the props for example the class name or an href that
we're passing here we can destructure the props and accept a class name as well as href and later on we also might
want to accept a specific on click or some children that that button might accept or even pixel values or just
color is it white or is it dark once we accept all of these values we can then render that button and we can just
return it like we are doing here but sometimes let's say we want to make our button a link and sometimes we want to
make it a real rectangular button to make that happen we can render two subf functions called con render button which
is equal to just an arrow function where we have an instant return keep in mind these are parentheses not curly braces
where we just return a button component and this button component will render a span element rendering the
children like this and it will also render a special button SVG component so we can do it like this button SVG to
which we pass the color white now this button SVG of course has to be imported so import button SVG from SL assets SL
SVG SLB button SVG and finally we can return the render button component and call it like so and of course we have to
make sure that our path is correct so just add an additional dot right here to ensure that we have the correct path now
back in our browser you can see that we have something that resembles a clickable button but right now it is
within hello world so let's continue modifying the Styles further I'm going to put our browser to the right side of
our editor and that way we can see exactly what is happening now when we're rendering this button let's give it some
additional classes by creating a new property at the top const classes is equal to and we can start defining them
here but before we start defining them let's use them within our button by simply saying class name is equal to
classes now if we give it a class name of something like a button you can see that it's automatically getting applied
right here something now let's make that something a bit more interesting let's make it relative let's make it inline
Das Flex let's give it items Das Center justify - Center h-11 for height transition Das colors on
Hover we want to make it text- color-1 now if you're passing some specific pixel values like this pixel
coming from props coming from the parent component then we're going to render it else we're going to render a default of
px-7 next if the white is true then we want to render a text n of 8 and else we want to render a text n off one and
finally if we have the class names we're going to render them else we're going to render an empty string this way we
ensure that all of the properties properties that we pass from our parent component into our button indeed get
passed to our button you can see that from our app we're passing something like padding top we're passing a margin
top of 10 and if we give it a margin top of 20 right here you can see how it changes it this is how you make reusable
components now I will go a step further here and make it even more reusable I'm also going to Define const span classes
and I'm going to give it relative and Z index of 10 we can also now apply the class name to the span element that way
we can change and modify the text within it now what if we don't want to render a button such as this one what if we want
to render simply a link well we can create a new function for that by saying const render link and then we can have a
return statement an automatic one again where we have an anchor tag like this that will have an
HF of href because this is a clickable link and we still pass over the class names from classes and then the span and
the button will be exactly the same so we can simply copy it here and now that we have render link and render button we
can choose when we want to render each one so right here we can say return if the hre property exists then we can
render the render link like this else we can return the render button there we go in this case we did pass the href so of
course in this case we will render a link but if we now remove the hre if we make it a regular button you can see
that it will look something like this all completely reusable and we'll be able to expand this component even later
on and make it more Dynamic for now this is good enough I just wanted to teach you how to create reusable components
now let's create another component which is more important than the button for now which is the header component so we
can head over to components and create a new header.
jsx we can run ource we can remove this import from react as it's no longer needed and
within our app we can remove this button we no longer need it but rather we can just surrender the
header coming from do/ compon components forward slhe header and we can also remove this H1 the reason we have this
padding top is because the header is fixed and we don't want it to overlap with the content so at the top will'll
show the knob bar with that in mind we can head over to the header and start creating it we can start with the
structure by returning a div element like this that has a class name equal to fixed top- Z and this will pin it to the
the top zindex of 50 to appear on top background of N8 over 90 backdrop Das blur Das small
this is a CSS property that adds elements backdrop it will kind of give it that glassy look we also want to give
it a border dasb for Border bottom border Das n-6 this is a border Coler and on large
devices background of N8 over 90 and on large devices backdrop off blur DSM now we cannot see anything yet because this
header has no content but as soon as we add the header you can see it here within this div let's create another div
that div will have a class name equal to flex items Das Center padding X of five on large devices padding X off
7.5 on extra large devices say padding X of 10 on Max large devices like this we can give it a padding y of four for top
and bottom immediately within here we want to render an a tag an anchor tag that will render the image of source is
equal to brain wave and this brain wave has to be imported from our assets by saying import brain wave from do/
assets there we go that's better already ready let's also give it a width of about 190 and a height of about 40 with
an Al tag of brain wave this anchor tag can have a class name equal to block W of something like 12 r on extra large
devices margin right of eight and an H ra off hash hero like this this is an ID used for navigation we want to specify
what happens if we click it and in this case if we click it we navigate over to the hero section now I can notice this
is a bit too close to the left side of the screen and I can notice that I didn't put it within this inner div so
let's move it over to inside of the div we created not that long ago there we go that's much better now below this anchor
tag still within the other div we can create a nav element and this nav will have a class name equal to Hidden fixed
top property of five REM left zero right zero bottom zero as well background of N8 on large devices static on large
devices Flex on large devices margin X of Auto and en large devices BG of transparent and of course I have to
spell the class name properly with a capital N now within this nav we can create a div to create some layout this
div will have a class name equal to relative Z of2 Flex flex-all items Das Center justify Das
Center margin of Auto so M Auto and on large devices Flex row and within it we want to show all of our items such as 1
2 3 and so on right now we cannot see them because they're dark and for that reason to more easily map over our nav
items we can create a new folder within our source called constants and within the constants we
can create a new file called index.js in the read me down below where you found all of the other class names
you'll also be able to find this constants file so simply copy it and paste it over here now you might wonder
300 lines oh my God is this our entire application coded for us but not really no this is simply different lists of
content of text that we'll be using throughout our application such as when we're going over the pricing section I
don't want you to hardcode all of these values rather we'll extract them from here and then map over them similarly
we're doing that for our navigation bar so if you see the navigation immediately here we create different link items with
a title URL and the ID so now we can go back over to the header and we can map over them we can do that by scrolling
over to the top and importing in curly braces navigation coming from do SL constants now we can
use that navigation right here by using a dynamic block of code called navigation and then mapping over it by
saying that map where we get each individual item item and for each item we instantly return something and that
something is an anchor tag this anchor tag can render the item. tile and it will have a key equal to item. ID as
well as an href equal to item. URL so now we're mapping over all of these properties and we're using the URL
and the title but if you save it we cannot yet see it and why is that well that's because this nav is usually
hidden so if we expand our browser you'll be able to see it right here features pricing how to use roadmap new
account and sign in so we can keep this view right here while we're styling them let's also give this anchor tag a class
name this class name will be dynamic and it will first turn each element into a block then it will also give it a
relative a font dcode which will apply a special font family text- 2XL to make it a bit larger
uppercase of course because we want to be able to click on these links easily text- n-1 to change the
color transition Das colors and on Hover text- color-1 of course make sure to apply to
the hover element and now if you hover that's already much better we also want to turn on a special property called
item.on mobile so some of these properties will only be showing on mobile and if that is the case then we
can do LG hidden which means we can hide that item on desktop or we can just apply an empty string which will look
like this now we can continue with the styling by giving it a padding X of six to create some spacing we can also give
it a padding y of six on medium devices we can give it a padding y of eight on large devices we can give it a
minus margin right of 0.25 on large devices text- Xs and on large devices f- semibold as well this
will make it look like this a bit smaller next we have to figure out which link is currently clicked meaning are we
in features or are we in pricing to do that we can can use a special property called use location from react router
Dom by importing in curly braces use location coming from react router Dom then right at the top of our
component we can say const path name is equal to use location and this will give us access to the current URL we're on
with that in mind we can scroll down and within the Styles we can check if the item. URL is triple equal to the
path name. has in which case we can apply a zindex of two we can apply on large devices a text-
and-1 and if that is not the case we can then give a class on large devices of text- and-1 over 50 so now we can see
all of them are gr out besides pricing or features or how to use this works for all of the links next let's also give it
on large devices a leading of five which will increase the line height and on large devices and hover we can also give
it a text n of one and on extra large devices we can give it a padding X of 12 so now we have something that looks like
this great finally on the right side of the screen we want to have a sign up we're trying to replicate this we want
to finally use this reusable button comp component we created not that long ago so we can head over below our div and
below our nav and create another anchor tag that will have an href equal to Hash signup and it will have a class name
equal to button hidden margin right of 8 text- n-1 over 50 and this simply allows us to
apply this Coler we have declared in tailin CSS config transition Dash colors which will apply a nice
transition once we hover over it and on Hover we want to modify the text color to N1 as well as on large devices set it
to block within this anchor tag we can say new account there we go we can see it here
and right below this anchor tag we want to create a button or rather we want to use our button component we have created
not that long ago so we can at the top just import it but by saying import button from SL button this button will
have a class name which will be hidden usually but on larger devices and larger it will be
visible and it's going to have an href off hash login and it will say sign in if we save it you can see how nicely
it appears on the right side now we're almost done with this desktop now bar but I can notice that it's not going all
the way to the end of the screen so if we head over to our first div we can see if we properly applied all of the
classes toab zero oh we're also missing the left zero right here to ensure that it's positioned on the Zero from the
left and we're missing a w- full it's for it to take the full width of the screen this is more like it we have the
primary navigation we have the new account and sign in and if we expand it this is looking wonderful on mobile
devices exactly the same as our deployed application but unfortunately there's absolutely nothing on our Mobile screen
that's because we'll Implement a completely custom mobile menu which looks like this you can open it and you
can close it so to get started creating our mobile navigation I'm going to help you to create the circles behind the
actual navigation you can see these circles and these little icons let's make that happen first and to make that
happen we can go to our file explorer and from the read me down below you can download the design folder unzip it and
then drag and drop it within our components folder within our design folder you'll notice that we have a
header. jsx file and here we have things such as Rings Sidelines background circles hamburger menu and we're then
using all of them right here within our app I think you can understand what those are rings are the Rings you see
around background circles are those bowls that you can see around as well and Sidelines are those vertical lines
you can see here and here the reason I wanted to provide you with this code is because all of these are hardcoded
values that we can play with and find the ones that work accurately for us it's just absolute positioning more or
less but if you think this code is confusing and if you're wondering how to properly use the absolute property I
would highly recommend to check out the absolute positioning inside relative positioning guide by CSS tricks the link
will also be in the read me with that in mind we can now go back to our original header and we can import two things one
thing is to import the menu SVG coming from assets SL SVG for/ menu SVG and the other thing is to import the hamburger
menu inside of curly braces fromd design slhe header and now we can
neatly combine this mobile menu with the desktop menu we had before so let's create a new use State at the top by
using the US state snippet let's call it open navigation and set open navigation and at the start it will be set to false
then we can modify this div by turning it into a template string like this and then checking whether we are
currently open or Not by saying if open navigation like this then provide a BG of
N8 else provide a BG of N8 over 90 and a backdrop blur small like this so now we of course have to
import Ed State coming from react and if you do that you'll get an error saying that the hamburger menu does not exist
that's because we misspelled it right here hamburger menu it's missing an R right here Burger once you fixed that
and reload we're back in Action so now let's go below this div that's wrapping our items and right here let's render a
hamburger menu a self closing component and also we have to make it show by going to our nav and modify the class
Name by once again making it a template string close it with a template string as well and then in here we can check if
the navigation is currently open so if open navigation in that case we can make it
Flex else we can make it hidden and then we can remove hidden from here now it's obviously false but if we
turn it to true through you can see the navigation menu of course we're going to leave it
to fals by default but now we want to go over below our signin button and add a new button this button will render the
menu SVG so it will look something like this it will have the class name equal to margin left of Auto and on large
devices it will be hidden margin left Auto will align it horizontally right here we can also provide it a pixel
property of PX3 and to this menu SVG it needs to know whether it's opened or closed so we
can provide it the open navigation state of course we want to somehow turn it on or turn it off like a toggle switch so
right here we can create a function called const toggle navigation that is equal to a function
that checks if the navigation is currently open in that case we can set open navigation to be
false and else we can set open navigation to be true also we can declare a function called const handle
click and once we click something we want to set open navigation to false because the last thing you want is have
something opened and then once you click on it to then have to go and close it you want everything to be closed
automatically once you click so now back in here let's attach this tole navigation to our menu
button by giving this button an onclick property of toggle navigation if we save it and if we click here oh nothing seems
to be happening but if we manually switch it to true you can see that works so that must mean that something with
the toggle navigation function is not good let's see if we're properly using this onclick property within our button
component and would you look at that this reusable component button hasn't yet learned how to use the
onclick so we can simply pass it to this button by saying onclick is equal to on click now if we go back and click here
you can notice that it opens although it's not looking exactly the same as the finished application right
so let's see what's wrong with the layout this hurger menu should have been rendered below this div right here that
way we can close the div and then have the hurger menu this will fix it just a tiny bit I also think we forgot to pass
an onclick listener to each one of our navigation items so we can do that by saying onclick is equal to handle click
we'll most likely have to look into to our div that's wrapping our entire nav or our entire header so let's see fixed
top zindex that's good we can remove this color from here as we're changing it in the open navigation backdrop blur
SM we can also remove it from here and let's see if that fixes it and it does this is great we have our vertical lines
we have our linear Rings everything is looking great and we can open and close our mobile menu as you can see the only
thing we've done is we've used this header component which then goes over the Rings Sidelines and background
circles which are basically nothing more than absolutely positioned values sometimes beautiful designs like these
but you might think how the hell did they do that well they simply use absolute positioning so now you know the
tricks now another important thing we have to do with this mobile navigation is Implement a special package called
screen lock it's this package right here and the only thing we'll use it for is to disable page scrolling this is for
mobile devices this will ensure that once you open up the page you cannot Scroll once you're here rather once you
click somewhere then the page will scroll automatically to that element so let's install it by going to our
terminal and running mpm install scroll lock let's go back to our header and and let's
import disable page scroll and enable page scroll which can be imported from scroll
lock finally once we toggle the navigation off we want to enable the page scroll so we can once again
scroll make sure to put the p as uppercased as it has to be so enable page scroll and once we turn on this
mobile menu then we can disable page scroll like this also once we click on a specific
element if not open navigation so if it's closed then we simply want to return we are not allowed to click then
and here we can just enable page scroll and set navigation open to false because that means that we clicked and
we are ready to go somewhere else and Scroll once again and with that in mind you have successfully implemented your
first major component the header not only this beautiful mobile header that looks like this with absolute position
values that once you click it leads you to a specific section but also this great desktop header which looks like
this you have the logo on the left you have some links in the middle you have the new account and sign in on the right
right this looks clean but what's even cleaner is this phenomenal modern hero section with this nice looking image a
great heading and a call to action button so without any further Ado let's get started not only with creating our
hero section but by creating a reusable section component which we'll use for all of the sections to come to start
creating a reusable section component we can start start creating it like we would any other component by creating a
new component within the components folder called section do jsx where we can run our afce to get it up and
running this component will act as a common skeleton which will reuse in all section components this component will
create all the lines between different components so to start working on this component let's first accept some props
such as class names or class name the ID of the section the crosses whether we have them or not crosses offset soon
enough you'll see what this is custom paddings and children once we have that we can return
our div and to that div we can provide some class names by giving it a class name of
and we want to make it Dynamic so we're going to do it like this and and give it a position of relative check if we have
custom paddings and then also provide all the other styles such as padding y of 10 on
large devices padding y of 16 on extra- large devices padding y of 20 then if we have crosses so if crosses then on large
devices we can give it a padding y of 32 and extra large off padding y of 40 else just render an empty string finally if
we're passing some additional class names we can just render them here or else just render an empty string now
within the section we can render the children so we can say children right here meaning whatever we pass into it
will be rendered right here and we can also create the divs for the sidelines let me show you what those are so on the
finished website if we go right here you can see those lines this one right here with those two crosses so we want to
differentiate our sections in this very very interesting way so to do that I'm going to collapse our browser to mobile
view and I'm going to create a div that will usually be hidden so it will have a class name of hidden it will be absolute
top zero left five with a width of0 0.25 h- full and BG off stroke -1 pointer events none on median devices it will be
block meaning visible and larger and on large devices left 7.5 to move it a bit away from the left corner and an extra
large we're going to give it a left off 10 similarly we can duplicate this one and make it the same same but for right
devices right 7.5 and right 10 and we also want to handle those crosses that you saw before
you cannot see them on mobile devices but you can see them on desktop devices so let's create a new Dynamic block of
code where we check for crosses and if the crosses exist we render a react fragment that has a self-closing div
this div will have a class name equal to it will be a dynamic string of hidden absolute top-
Z left- 7.5 right- 7.5 as well h- 0.25 for the height BG d stro-1 and a
dynamic block of code if crosses offset exists then we render the crosses
offset like this also we're going to give it pointer events none and what this does is this disables all the
pointer events so we canot click it on large devices we will show it so it will be block usually it will be hidden on
extra large we'll give it a left of 10 and write of 10 usually like this now if we go back to our website still nothing
is happening because we haven't yet used this section and we will use it very very soon but before that we want to
import those crosses at the top by saying import section SVG from assets SL SVG SL section SVG and
then we can use it right here if we have crosses below this div by simply saying self-closing component of section SVG to
which we pass the crosses offset if it exists there we go so now we ready to finally
use this section and before we use it you can see that we have one warning right here and that is that the class
name is missing in props validation this is just an eslint warning which we can fix if we go to eslint rc. CJs if we go
to rules and then add an additional rule that's going to say react slpr types will be set to off like this and of
course we have to close the string here and now if we go back to our section you can notice that it's no longer
complaining it is now just giving us a proper warning that the ID is not being used and we do want to pass that ID over
to this div ID is equal to ID and finally we are ready to use this section within our application and what
other section will we use it for rather than our hero section so let's create a new component within the component
folder called hero. jsx just run rafc and let's immediately
consume it within our app.jsx just below the header we want to render a hero section looking like this
hero there we go that's pretty simple right now we can go into the hero and we can start developing it the interesting
thing here is that we're not going to wrap it in a typical div rather we're going to wrap it in our
section which we have created just before so we can import this section coming from that slash section and if we
save it you can notice how it pushes it down just a tiny bit and if I expand it you can also notice that it applies some
vertical lines although it's very hard to see right now it'll be easier to see as we pass some additional properties to
it for example I'm going to return this properly so it's easier to to see and I will pass our section some more props
that it wants such as a class name of pading top of 12 RM and minus margin top of
5.25 RM I found those values to work the best you can see how it shifts it and we can also continue adding some more
properties such as crosses as well as a crosses offset property of large
Translate Y of 5.25 RM like this we can also give it a property of custom paddings and we can
give it an ID of hero as this is our hero section if we save it and expand our browser you'll see that not a lot is
happening right now we cannot see any crosses or anything that's because we don't yet have enough content within our
hero section so let's change that let's wrap our section with another div and this div will have a class name
equal to container and relative within this div we'll create another div and that div will have a class name equal to
relative Z of One Max DW of 62 R MX Auto this is for margin horizontal Auto and this will simply align all of
the elements horizontally we can also give it a text Center to show the text in the center we can give it a margin
bottom of about four Ram to provide some spacing on medium devices we can give it a margin bottom of 20 and on large
devices we can give it a margin bottom of about six REM as well finally within this div we can create a new H1 that
will have a class name of H1 this is a special class we created before as well as a margin bottom of six and
within that H1 we can say explore the possibilities like this and we can also copy whatever else we say here explore
the possibilities off AI chatting with brainwave so let's simply copy it paste it here the deployed website will be
mentioned in the description down below so you'll be able to copy all the content from it and then within this H1
we also want to create a SP Anan element and this span will have a class name equal to inline Das block and also
relative here we can say brain wave now below brain wave we want to also render a self-closing image tag
this image will have a source equal to curve and this Curve will be coming from assets it will look something like this
and we can also give it a class name equal to absolute top- full left- Z w- full and on extra large devices we need
to reposition the bit to fit below brain wave to minus margin top of two there we go we can also give it a width of about
624 and a height of about 28 I found those values to work the best alongside with an Al tag off curve now we can head
below this image below the span and below the H1 and we can create a P tag which will form our
subheading that subheading will contain all the text below which will be this one you can just copy it and it can say
Unleash the Power of AI within brain wave let's style it a bit by giving it a class name of body -1 let's also give it
a Max dw-3 XL margin X of Auto margin bottom of six text- n-2 and on large devices margin bottom
of eight right below this P tag we want to show a call to action button so it will be a button component which we need
to import from that slash button I did that automatically right here at the top and that button since it's our component
we can pass it on HRA of forward slash pricing and we're going to give it a special property of white and then we
can say get started there we go now we have a white button now this button is not looking great right now you can see
the text is not centered so let's go into the button and let's see if you apply white why is it not centered and
usually it is it looks like our classes are just a tiny bit wrong so we do all the great stuff such as inline Flex
relative item Center justify Center as well then we apply padding and then we have this white property where we apply
text n 8 or text n one and then after that we apply a class name the issue is the typo I have right here where it says
inline it rather should be in line and there we go now our button is fixed as well now below that button we can start
creating the rest of the structure which is quite exciting so we can go below below the button and below the div and
create another div which will be the container for the rest of our hero section with a class name equal to
relative Max DW d23 REM margin X off auto on medium devices Max dw5 XL so it has a lot of width and on extra large
devices margin bottom of 22 within that div we'll create a another div to keep building out that
hero structure with a class name equal to relative Z of one padding of 0.5 rounded Dash to Excel and we also
want to apply this bg-- gradient within that div we want to create another div and that div will
have a class name equal to relative BG d n-8 rounded D1 REM like this and within that
div trust me this is the last one we're going to create a self-closing div that will have a class name equal to h- 1.4
Ram BG of n10 rounded dt- 0.8 remm that's going to give it this grayish rectangle and below it we
can have a d within which we'll show this great looking robot image with a source equal
to robot coming from do do/ assets we're going to also give it a class name equal to
w-o we're going to give it a width of about 1440p and a height of about 1,800 pixels
with an Al tag of hero as in hero section that's looking great now let's style the div wrapping the robot it will
have a class name equal to aspect -33 over 40 this is the aspect ratio and let's of course call it div as it is
then let's give it a rounded dasb of 0.9 REM like this let's also give it an overflow hidden so we cannot scroll
through it and on medium devices let's modify the aspect ratio so aspect Dash 688 over 490 I found those values to
work the best and on large devices we also want to play with it a bit by saying aspect
d124 over 490 this will make it look good on all different kinds of devices and screen sizes now let's go one two
three divs down and below it we're creating one last final div and within that div we're creating
the image that will be the hero background so here we can say Source equal to Hero background coming from do/
assets let's give it a class name equal to w-o and looking at it right now I think
I provided the class names of this image to the image above so we want to take this width and the height and the AL tag
from the robot over to this below one so we want to do it like this with 1440p height 18800 alt is hero and that's
going to give us this great looking background for now this background appears below the robot but soon enough
it will look like this it's going to come from behind it to do that let's add more properties to our robot such as
width of 10,24 and height of 490 and Al tag of AI now let's add the class names to this
div wrapping the hero Background by giving it a class name equal to Absolute minus stop minus or Dash
54% this will make it appear below or rather behind this image we can give it a left- 1 over2
which will move it a bit away but then we can give it a width of 234 per which would make it a bit larger we
can also then use the translate property so minus translate specifically dx1 over 2 that's going to look like
this and now it's going to appear right behind it then on medium devices we want to play a bit where we show it so it's
going to be minus stop- 46% like this on medium devices W will be
138% and on large devices minus stop Dash 104% there we go so now we have this
beautiful looking hero section as you can see and if we expand it you'll see that
it's looking great but not perfect as it says curve right here we want to remove that part where it says curve rather
that is just the actual component or the image there we go and if we compare it with the finished product we're still a
bit off right it looks a bit different so going back now we can make the fixes for desktop devices here we're missing
the positioning in RS you can use RS you can use pixels whatever you prefer this one is 84 pixels and it seems to me that
the image is definitely not looking good so it's not positioned correctly as you can see right here so let's scroll down
to where we have our AI robot and let's provide it some class names other than w full for example we can give it a scale
of Dash 1.7 a translate of Y of 8% which will bring it a bit up and then we want to
play with that scale and translate on different devices such as on medium we can set the scale to be one on medium we
also can do the minus translate dy- 10% and on large devices we can do a
minus translate of Y of 33% so now if we save it you can see
that it looks much closer to the final design although we're definitely missing some space between our header we're much
closer than we were before as you can see on the final website we have these moving circles which we already
implemented before as well as these circular rings that go in the middle of the screen so let's implement it to
start implementing it we'll get some help from the package called first we have to install it react just Parallax
so react Parallax and then we'll use the same Rings we have used before from design but this time in the hero you can
see gradient bottom line we have different rings and all of that is being displayed within background circles and
these little things within thises that are mounted these are the WS that you can see flowing around so now to
implement those rings and circles and everything we can head over to the hero section that we have developed and we
can import everything we need we can import the background circles bottom line as well as
gradient coming from.des slh hero we can also import something known as hero icons coming
from do/ constants and let's not forget the Parallax we can import the scroll
Parallax coming from react just Parallax and it looks like we have to fix the import for our
hero we are right now within hero so it's going to be just slash design hero there we go now to make it work we can
give a ref to our div of the hero section by saying ref is equal to Parallax ref
and we can Define that ref right here by saying const Parallax ref is equal to use ref which is a hook which we have to
import at the start equal to null once we have that ref we can navigate over below our image of the robot of the AI
and then there we can render the scroll Parallax coming from that package which we just
installed there we can say is absolutely positioned which is one of its proper and we can render a UL or an unordered
list within it we can give it a class name equal to Hidden absolute positioning as we said
it will be a minus left of 5.5 Ram a bottom of 7.5 REM padding X of one padding y of one
background of N9 over 40 back backrop blur border and Border D n-1
over10 let's not forget to make it a bit rounded of to XL and on extra large devices it will be Flex now within there
we'll be able to show all of these different icons that you can see here floating around so if we go back within
this UL we can open up a dynamic code and say hero icons. map where we get each individual
icon and an index for that icon and we can immediately return An Li that has a class name of padding of five so
P5 and a key equal to index and within it we render an image that has a source equal to Icon a width of about 24 a
height of about 25 and its alt tag will be equal to just icon now if we save this you can see this menu appeared
later on we can make it clickable as well and you can see how it flows we have this Parallax effect which is
really cool and it is done by the library we installed two devs down below that Parallax we want to render a self-
closing gradient component which looks like this and this will give it this nice looking gradient to make it really
pop and then going below this background hero that we have here specifically one div below the image we want to render
the background circles which we also created not that long ago and this will make it move like this now this hero is
looking much closer to the finished website let's see where is it missing some top margin from if we check out our
hero section here we're giving it a padding top of 12 REM but if we go within the
section let's see if we're actually implementing that class so if we really make make sure that everything is nicely
divisible we have relative we then start with custom paddings so if custom paddings are applied appli them else
apply all of these Styles right here and then at the end apply class names now make sure that this code is exactly as
it is here and then it will work most likely had a typo somewhere and if it still doesn't work you can refer to the
finished section. jsx code so simply copy it and overwrite it but once that is done you'll be able to see that now
our hero is looking amazing also notice that we're seeing brain wave two times so if I go back to my hero section and
look at brain wave we don't have to see it for the second time we have it within the span
element and we have to provide some space like this so now it looks great amazing job building this hero section
you can see that now it's very similar to exactly how it looks like on the deployed application we'll do some more
improvements soon but even for now this is just absolutely amazing great work now the only thing that our hero is
missing for it to be perfect are these little jumping add-ons these cards that go up and down where we can see what we
can do within this AI app such as code generation and also this AI is generating also I notice we have a bit
of a different text spacing so if we go to our deployed application you can see that a I is at the top whereas here it's
at the bottom which has a bit of a nicer text hierarchy so going back to where we are saying possibilities of AI right
before off we can render the N sign and say NBSB and then a semicolon and we can also put that after AI so let's just do
it right here before and after AI that should be better so now if we save it you can see off space AI space and then
chatting with but make sure that there's no space between semicolon and chatting with then it's going to look exactly
like this which is now much more similar to this and also it looks like I misspelled possibilities great with that
said we can focus on what matters which is implementing those flying add-ons to our robot screen so first let's focus on
this AI is generating text I'm going to go back to our code and if you look at here we have a bit of a warning where it
says that the bottom line is never used so just before we Implement those little add-ons we can scroll to the bottom and
right before we're closing the section we can also use this bottom line component now let's go back to the
components and create our first flying component this one will be called generating dot jsx it's going to be a
simple rafc component that's going to say generating and it's gonna render only a single image and a piece of text
this image will have a class name equal to W5 h-5 and margin right of four and we can
also give it a source equal to loading so this will be our loader and this loader we can import loading from
do/ assets and then we can also give it an Al tag of something like loading and we can also say AI is
generating now if we save that it's going to be nowhere to be found but now as soon as we style this
div by giving it a class name equal to it's going to be a dynamic template string and it's going to have classes of
flex items Das Center h-3.5 REM padding X of 6 background of N8 over 80
and rounded Das 1.7 REM finally it needs to render all of the class names that we passed to it so we can see class name
here and then render class name or an empty string if we don't have any and we can also give it a text Das base this
will just provide it a typical font size and line height so it looks good now we want to use this within our hero section
so let's go to our hero and let's scroll up above our scroll Parallax and here we can render the self-closing generating
component which we of course have to import at the top by saying import generating from slash generating and it
won't be within curly braces that's my bad if we save it we still cannot see it and that's because we have to pass some
additional props or styles to it specifically we have to make it absolutely positioned by giving it a
class name of absolute left -4 right D4 and bottom-5 now on medium devices we can
modify the left to 1/ two and on medium devices we can make it right- Auto on medium devices we can also modify the
bottom to eight and on medium devices we can modify the width to about 31 Ram like this and on medium devices we can
also use the dash translate or minus translate X1 /2 this is just to ensure that we properly position it on top of
our image which you can see right now looks absolutely perfect later on we can even make this SVG spin so it feels like
it's generating something and now the last thing we have to do is this code eration card and we
can create it by creating a new component within the components folder and we can call it a
notification. jsx we can run RFC and we can immediately use it within our hero it's also going to be within
its own Parallax so let's recreate another Parallax scroll Parallax that means that it's going to
move up and down it will be absolutely positioned and there we can render the self-closing
notification component coming from do/ notification and we can also automatically pass some properties to it
we can pass a class name equal to usually hidden but on larger devices will be able to see it absolute minus
right- 5.5 remm bottom of 11 REM w -8 RAM for width and on extra-
large devices Flex meaning visible we can also give it a title of code generation this will be what the
notification will say and now we can go into the notification and start creating it we can accept the props we passing
into it such as the class name and the title and we can start styling our div by giving it a class name equal to
it's going to be a dynamic template string where we first render the class name or an empty string if it doesn't
exist in this case it will because we're making it absolute we can also give it a property of flex items Das Center
padding off four padding right off six background of N9 over
40 backdrop Das blur to make it feel like it's glassy border border dn1 over 10 which is the
Coler rounded - 2XL gap of five and that's it already you can see this notification appear
finally we can wrap it within a div that has a class name of flex -1 and there we can render an
H6 this H6 will have a class name equal to margin bottom of one font Das semi bold and justify between and it will
render the dynamic title we're passing from props now it says code generation right below this age6 we're going to
create a Dev where we have a class name equal to flex items Das Center and justify between and now that I look at
it this H6 doesn't need to have a justify between it's going to have a text base to modify its font size and
line height within this inner div we're going to have a UL that will have a class name equal to
flex minus margin of 0.5 and then within this we can map over our images of the users generating
something with AI by saying notification images which we can import from constants that map where we get each
individual item and the index and we can immediately return An Li that renders a self-closing image with a
source equal to item a class name equal to w- fo a width of 20 and a height of 20 as well so let's fix it and let's
also give it an ALT tag of item now if I save this you can see all of these different user avatars
let's style them a bit by giving this Li a key equal to index and a class name equal to flex
w-6 h-6 border of two border dn-12 and most importantly rounded Das
full which will turn it into full circles and overflow hidden so we cannot actually scroll through them there we go
this is much better notice how in the final version we have this image of what they're generating so we can add that to
our application as well by adding an image Above This div with a flex of one this will be self-closing image with a
source equal to notification one coming from assets with a width of 62 a height of 62 and then I'll tag of image there
we go go that's better already and we can also make it a bit rounded by giving it a class name equal to rounded
DXL there we go the last thing we need is a text that says 1 minute ago so to do that we can scroll down and right
below the UL we can create a div that will have a class name equal to body -2 and text-
n-13 and it's it can say 1 M ago there we go now this is looking more like it it's Fuller and these things
scroll up and down if you want to make the AI is generating also scroll up and down you can simply wrap it in this
scroll Parallax in case you want to do that there we go so generating you wrap it into a scroll Parallax and save it
and you can see that now it moves as well but now it feels like too much is happening I want to leave this here and
only let those two move up and down so I'm going to bring this back to what it was great finally the last part of the
hero that they're missing is helping people create beautiful content ad and then these different logos right here so
that's going to appear below the hero section or rather still within it but a bit below so to create that last hero
component we can go to components and create a new file called company logos. jsx where we can run
RFC and we can go back to the hero and immediately use it within here that's going to be all the way at the bottom
below background circles below a div and then right here company logos imported from that/
company logos and we can also provide it a class name equal to Hidden on smaller devices
relative Z of 10 margin top of 20 and on large devices block so it's actually visible and now you should be able to
see it somewhere here at the bottom but it's quite dark so you cannot see it so let's go into the company logos and
let's make it appear exactly how it should be we can do that by accepting these class names that we're providing
and then applying them directly to our div class name is equal to class name that will make it appear right here at
the bottom then within this div we also want to render an H5 that will say helping people create
beautiful content at and then we want to start listing those logos so we can remove
this company logos we can style this H5 a bit by giving it a class name equal to tagline margin B bom of six text- center
and text- n-1 over 50 that's much better and below the H5 we can render a UL that's going to have a class name equal
to flex and it's going to render or map over company logos coming from constants map where we get each
individual logo an index of that logo and we return An Li for each one of these that renders a self-closed image
with a source of logo a width of about 134 a height of about 28 and then we can also say alt is going to be that actual
logo if we save it you can see all of those logos at the bottom and to style it a bit we can give this Li a class
name of flex items Das Center justify Das Center Flex D1 and H -8.5 RM and of course we have to also
give it a key equal to index if we save it you can now see those beautiful logos and now we can say
that our hero section is looking wonderful this is one of the most modern designs I have seen in the long time
these circles or bols move as you scroll but still they're not taking away your attention you have those circles or
rings actually bringing your attention to this button and to this image here these cards nicely float showing you
what you can do with this software and then you get instant approval by seeing other companies using this software as
well now that this hero is spared with our wonderful Navar this is looking great and let's not forget that it's
also looking amazing for mobile devices you can open it up you can close it scroll down and here we remove or get
rid of some of the Clutter you don't want to show all of these cards if you don't have enough space on desktop
devices we have space here we don't so we hide them so that is it for the hero section phenomenal job on coming this
far but don't forget this entire time we haven't been just building the hero section or the Navar we set the
foundation for everything else we're going to build we have the reusable section component which now creates
these rectangular lines on desktop devices and we have also set up the entire file and folder structure so that
now we can simply render an additional section below the hero section specifically the next one will
be this one we're going to call it benefits where it says what you can do with this app such as ask anything
improve every day connect anywhere or much more it looks great on mobile devices but it looks even better on desk
stop so let's go ahead and create the second big section of the day which is our benefit section and snap I just
changed our Visual Studio code theme to make the video a bit more interesting I switched it to a theme called one dark
Pro whereas before I used this cpin theme what do you think of this one let me know in the comments down below which
one you prefer but with that said let's continue with the video we want to focus focus on another big section of this
video which is the benefit section so we want to add this tagline as well as these beautiful cards indicating
different benefits of our application so to implement it we can create a new component within the components folder
called benefits. jsx in there we can run our AFC and
immediately we can import those benefits right below our hero so we can say a self-closing benefits which we can
automatically import from components now if we go into the benefits we can start creating them and
we should already see benefits right here at the bottom although it's quite hard to notice but we will be able to
notice it once we wrap our benefits into a section component coming from do slash section this will give it some space and
nicely position it on the screen we can also give it an ID equal to Features so we can later on scroll through it
dynamically from the navigation bar and what do you say that within this section we also have a div with a class name
equal to container relative and a z of two within this div we can render a special heading
component this is a component that we haven't created yet so we can create it right away by creating a new heading JSM
X component and run our fce then we can simply import it within our benefits just like this and now we can
see heading and to this heading we can pass to props we can pass a class name prop allowing us to further style our
heading and we can also pass it a title prop in this case it can say something like chat smarter not harder with
brainwave and we can paste it right here there we go so now if we go back into the heading we can accept these class
names as well as a title coming from props and we can use them when creating this heading so right here this heading
will be a very reusable component it will allow us to use it as a title as a subtitle as a large text tagline and it
will take many more forms so right here we can check if we're getting the title and then within this div we can say
title and and render an H2 that will render this title and we can also give a class name to this H2 to be equal to H2
now if we save this and go back you can see chat smarter not harder with brainwave we also can do something with
