This is a Next.js project bootstrapped with create-next-app
.
First, run the development server:
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
Open http://localhost:3000 with your browser to see the result.
You can start editing the page by modifying app/page.tsx
. The page auto-updates as you edit the file.
This project uses next/font
to automatically optimize and load Inter, a custom Google Font.
To learn more about Next.js, take a look at the following resources:
You can check out the Next.js GitHub repository - your feedback and contributions are welcome!
The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.
Check out our Next.js deployment documentation for more details.
npx create-next-app@latest
as it says in https://nextjs.org/npm run dev
favicon.ico
in the app
folderapp\globals.css
app\layout.tsx
app\page.tsx
, delete everything with the return
of this page, and instead set some basic markup & Tailwind CSS classesTailwind CSS IntelliSense
& ES7+
tailwind.config.ts
, add your first custom color by extending your actual themeapp\page.tsx
& refer to that customized colorBuild a top title, a primary title, a subtitle & the call to action button to show your work
components
Hero.tsx
rafce
to quickly create a Home()
component function (feature from ES7+ React/Redux/React-Native snippets
)app\page.tsx
, output the <Hero />
component imported from components\Hero.tsx
components\Hero.tsx
, set some classes to the <div>
<div>
create another <div>
acting as a wrapper for your first components coming from Aceternity to add the spotlight effects available in your Figma design in desktop versionCtrl + K
to open up a search no matter where on the page you arespotlight
& press Enter
Ctlr + K
server actions
& press Enter
Ctrl + F
& search for use server
spotlight
to reach out to https://ui.aceternity.com/components/spotlight
npm i framer-motion clsx tailwind-merge
npm i framer-motion clsx tailwind-merge
utils/cn.ts
utils
folder & add a new cn.ts
file & in there paste the code you copied beforecomponents/ui/Spotlight.tsx
components
folder, create a new ui
folder, inside of which you create a new file called Spotlight.tsx
& paste what you just copiedspotlight
animation into tailwind.config.js
file”, copy the code
tailwind.config.js
, paste the code you just copied to override the contentCtrl + K
& search for Add utilities
, you’ll see that you have to add this flattenColorPalette
in tailwind.config.js
by overriding the code in your tailwind.config.js
tailwind.config.ts
tailwind.config.ts
tailwind.config.js
file with the code you just copiedapp\globals.css
tailwind.config.ts
file, so in your terminal, run:
npm install mini-svg-data-uri
npm install tailwindcss-animate
<Spotlight />
component within components\Hero.tsx
inside the previously added <div>
<Spotlight>
component & fill="white"
<div>
that contains this spotlight, create another <div>
that will act as a UI grid
Code
to switch over the code & copy the 2 <div>
s with the <p>
tag in between & paste it therenext-themes
available in https://www.npmjs.com/package/next-themes to switch the background to dark
npm i next-themes
npm install next-themes
in your terminalapp
& create a new file called provider.tsx
<ThemeProvider>
layoutapp\layout.tsx
& wrap your {children}
with it & import { ThemeProvider }
from ./provider
defaultTheme
to "dark"
components\Hero.tsx
<div>
that will wrap your heading below the <div>
containing your grid & give it some CSS classes<div>
with some CSS classes<h2>
that would say “Dynamic Web Magic with Next.js”<h2>
text appear over the grid by setting the grid to a position of absolute
& less noticable by giving a background color of dark:bg-grid-white/[0.05]
<h2>
, render your primary text & give it its animation
Text Generate Effect
components/ui/text-generate-effect.tsx
components\ui
, add a new file called TextGenerateEffect.tsx
& paste in there the code you just copiedcomponents\Hero.tsx
& use this <TextGenerateEffect />
& pass to it 2 props className
& words
<TextGenerateEffect />
output a <p>
tag to add the subtitlecomponents\ui\TextGenerateEffect.tsx
, modify some of the content
motion.span
CSS class dynamic to turn the “Experiences” word into purplemt-4
with my-4
text-2xl
CSS class to make the text in the words
biggerTailwind CSS buttons
ui
folder, create a new component called MagicButton.tsx
& create a new React component with help of the rafce
shortcutcomponents\Hero.tsx
& render the <MagicButton />
component in therecomponents\ui\MagicButton.tsx
, make the button more dynamic with help of props to render some dynamic content & updated some of the CSS classescomponents\Hero.tsx
& render some props to <MagicButton>
title
icon
react-icons
https://www.npmjs.com/package/react-icons by running npm i react-icons
in your terminalFaLocationArrow
imported from react-icons/fa6
to the icon
propposition
set to right
components/ui/floating-navbar.tsx
ui
folder, create a new component called FloatingNav.tsx
app\page.tsx
& output the <FloatingNav />
component & pass to it the navItems
prop like it says in the docs under “Props”components
folder, add a new Grid.tsx
component
rafce
shortcutapp\page.tsx
, import that <Grid />
componentcomponents/ui/bento-grid.tsx
ui
folder, creater a new component called BentoGrid.tsx
components\Grid.tsx
, import the 2 <BentoGrid>
& <BentoGridItem>
components available in components\ui\BentoGrid.tsx
<BentoGrid>
, render an array in which you add an object with a title
& a description
& an id
field<BentoGridItem>
component<BentoGridItem>
the required couple of props according to the docs under “Props”BentoGridItem
component in components\ui\BentoGrid.tsx
id
propdata
folder & inside of it, create a new index.ts
filecomponents\Grid.tsx
& storing it in a gridItems
constantcomponents\Grid.tsx
, import the gridItems
constant & map it like you did beforeREADME.md
of the original project https://github.com/adrianhajdin/portfolio/blob/main/README.mdCode to Copy
to reach out to this page https://github.com/adrianhajdin/portfolio/blob/main/README.md#snippetsdata/index.ts
& copy the code & paste in your data\index.ts
fileAssets
, click on here
to download the public
folderpublic
folder & replace it with the new downloaded onecomponents\Grid.tsx
, add some more props to the <BentoGridItem>
components\ui\BentoGrid.tsx
, accept those props nicely in the BentoGridItem
component so that you can put them to useBentoGridItem
according to those props so that the cards look nice
style
attribute with some background
color & backgroundColor
gradient provided from https://github.com/adrianhajdin/portfolio/blob/main/README.md#snippets under Linear Gradient
<div>
& inside of it add
<div>
with some CSS classes & an <img />
in it<div>
for the secondary image<div>
only for the sixth item to render an animation called Background Gradient Animation
from Aceternity UI
components/ui/background-gradient-animation.tsx
ui
folder, add a new GradientBg.tsx
file & paste the code you just copied in there<BackgroundGradientAnimation>
component in this inner <div>
<div>
with some CSS classescomponents\ui\GradientBg.tsx
, properly import {cn}
<div>
with some CSS classes & another div
with some CSS classes & inside of it some {description}
{title}
with some CSS classesthree-globe
, which would be another Aceternity component, for the second card
components/ui/globe.tsx
ui
folder, create a new Globe.tsx
file & paste in there the code you just copieddata/globe.json
file
Copy the globe json
& click on Download the globe.json file from this URL
data
folder, create a new globe.json
file & paste the code you just copied in thereInstall Globe dependencies
& copy the commandcomponents\ui\BentoGrid.tsx
, below the <div>
that wraps the description
& the title
<GridGlobe>
component imported from './GridGlobe'
for the second grid item cardCode
to switch over the code & copy the codeui
folder, add a new GridGlobe.tsx
file which would be the representation of the Globe
component within the gridglobeConfig
prop we need & import the Globe
from './Globe'
components\ui\GridGlobe.tsx
, in the GridGlobe()
function component to customize it as we want it by cleaning itcomponents\ui\BentoGrid.tsx
, fix the styles of the container to make the globe not jump out of the card which matters a lot for all these elements of each one of the cardsid 3
, which would be the Tech Stack list
components\ui\BentoGrid.tsx
, below where you rendered the second card, add a <div>
with some CSS classes<div>
with some CSS classes<span>
<span>
with some CSS classes for the empty list item with a background color<div>
containing this left list & paste it below it & change some of the tech & move the <span>
for the empty list item above the mapped listid 6
, which is the one with the gradient in which the user will be able to copy your email
id 3
, add some dynamic content & an outer & inner <div>
with some CSS classes<div>
, render a lottie animation
react-lottie
package & also installing its types by running npm i --save-dev @types/react-lottie
<div>
, output the <Lottie />
component & give it some options
prop which contains an object of
loop
property, which is going to loop only when we copy the email, so create a copied
state because you need to have access to the state of copied & set this field to copied
autoplay
which also has a copied
valueanimationData
with a value of animationData
which would be another JSON object to add to your data
folder
data
folder, create a new confetti.json
filerendererSettings
object, which you can add to it a special preserveAspectRatio
with a value of 'xMidYMid slice'
'use client'
component, because you used a useState()
<MagicButton>
to trigger the animation
handleClick
prop which trigger a handleCopy
functionhandleCopy()
functioncomponents\ui\MagicButton.tsx
, add a onClick
prop that points at this handleClick
functioncomponents\ui\GradientBg.tsx
, replace h-screen w-screen relative
with h-full w-full absolute
This section on your list will be what your portfolio is all about which is displaying the recent projects you worked on using this very engaging card that folds back and allows you to visit the live website that you’re seeing on the screen This is a very cool effect, so let’s go ahead and implement it now
components
, create a new RecentProjects.tsx
fileracfe
to create a RecentProjects
componentapp\page.tsx
, output the <RecentProjects />
componentdata\index.ts
, customize the projects
array to really make it your projectsRecentProjects.tsx
h1
headingimport { projects } from '@/data';
& mapping the projects
3D Animated Pin
which will pin on these project cards
Copy the source code
for components/ui/3d-pin.tsx
, copy the code belowcomponents/ui
, add a new 3d-pin.tsx
file & paste the code you just copied in therecomponents\RecentProjects.tsx
& use this <PinContainer>
componentcomponents\ui\3d-pin.tsx
to customize this <PinContainer>
components\RecentProjects.tsx
, customize this <PinContainer>
component by
title
, the description
& the bottom
of the cardsapp\page.tsx
<FloatingNav>
component{navItems}
coming from '@/data'
components\ui\FloatingNav.tsx
Login
buttoncomponents\RecentProjects.tsx
, make the Projects
navbar link point to the “Projects” section by adding id="projects"
With this many features completed on your developer portfolio, it’s important to ensure a smooth user experience, optimized performance and just in general showcasing that you’re using all the best practices of developing applications.
So, let’s get started with integrating Sentry
Install Sentry
Next.js
as your frameworkConfigure SDK
SENTRY_AUTH_TOKEN
.env.local
file & paste the provided token in thereConnect to my central instance
or View Issues
to get redirected to https://<your-project>.sentry.io/issues/
& see the Issues
sentry-example-page
folder with a page.jsx
file are created
sentry-example-page
& paste it to your site URL, like this http://localhost:3000/sentry-example-pageThrow Error
Issues
dashboard in sentry.ioError
to analyze itQueries
, Requests
, Web Vitals
, and especially in this case, User Feedback
User Feedback
Set Up Now
Sentry.feedbackIntegration
in the sentry.client.config.js
file within your code & set the colorScheme
to dark
Report a Bug
buttoncomponents
, create a new Clients.tsx
file & run rafce
& add your customized content
<h1>
Infinite Moving Cards
components/ui/infinite-moving-cards.tsx
components/ui
, create a new InfiniteMovingCards.tsx
{ cn }
importcomponents\Clients.tsx
, output the <InfiniteMovingCards />
component & set to it all the required propscomponents\ui\InfiniteMovingCards.tsx
& style those cards to your likingcomponents\Clients.tsx
& add a div to wrap the companiesapp\page.tsx
& output <Clients />
components
, create a new Experience.tsx
file & in there
rafce
<h1>
<Button>
provided by Aceternity UI
Moving Border
components/ui/moving-border.tsx
components/ui
, create a new MovingBorders.tsx
filecomponents\Experience.tsx
& use the <Button>
component imported fromcomponents\ui\MovingBorders.tsx
& style the Button()
componentapp\page.tsx
& output <Experience />
components
, create a new Approach.tsx
file
rafce
Canvas Reveal Effect
components/ui/canvas-reveal-effect.tsx
components/ui
, create a new CanvasRevealEffect.tsx
fileCode
& copy the codecomponents\Approach.tsx
CanvasRevealEffectDemo()
with Approach
{ CanvasRevealEffect }
importAceternityIcon
function & return a Magic Button from Aceternity UICard
functionapp\page.tsx
& output <Approach />
The next thing you can focus on is this minimalistic yet quite effective footer so let’s do it next
components
, create a new Footer.tsx
fileapp\page.tsx
, output <Footer />
app\page.tsx
, remove overflow-hidden
so that the page is not cut off when scrolling back up after clicking the nav buttonsoverflow-clip
to remove this extra horizontal scroll that appearedcomponents\Footer.tsx
, remove the <div>
containing the grid image to avoing extra space at the bottom of the pagecomponents\ui\FloatingNav.tsx
, fix the floating navbar for mobile view by removing hidden
components\Footer.tsx
, add more space to the footer for mobile view & reduce some extra space for desktop viewnext.config.mjs
, inside of nextConfig
, set output
to 'export'
& typescript: {ignoreBuildErrors: true}
app/sentry-example-page
& the app/api
foldersnpm run build
out
folder & click Reveal in File Explorer
& copy all the files in out
& paste it in your hosted website folder