20
loading...
This website collects cookies to deliver better user experience
Note: This article doesn't describe the build step-by-step but showcases some important highlights of the process.
mkdir portfolio && cd portfolio
npm init astro
site.json
file inside a data
directory in the src
of the project.{
"title": "Chris Bongers | Senior Full Stack Developer",
"description": "Chris Bongers - Portfolio, Full stack developer",
"url": "https://chrisbongers.com/",
"author": "Chris Bongers",
"profile_pic": "/assets/chris.jpg",
"resume": "/assets/resume.pdf",
"nav": [
{"link": "#skills", "name": "Skills"},
{"link": "#work", "name": "Work"},
{"link": "#footer", "name": "Contact"},
{"link": "https://daily-dev-tips.com/", "name": "Blog", "target": "_blank"}
],
"skills": {
"comfortable": [{"name": "HTML5", "icon": "html5"}],
"mastering": [{"name": "Flutter", "icon": "flutter"}]
},
"work": [
{
"title": "Yaatree",
"description": "Our amazing puppy, who goes on all kinds of cool adventures",
"image": "/assets/yaatree.jpg"
}
],
"journey": {
"2030": [
{
"title": "Senior full stack remote developer ☁️",
"description": "It's my dream to be a senior full-stack developer who can work remotely."
}
]
},
"testimonials": [
{
"image": "/assets/nicole.jpg",
"name": "Nicole Bongers",
"title": "~ Wife",
"quote": "Chris is an amazing husband and dog father!"
}
],
"socials": [
{
"link": "https://codepen.io/rebelchris",
"title": "Codepen",
"icon": "codepen"
}
]
}
index.astro
page, this is the actual index, and for us, the only page we have.---
// Component Imports
import MainHead from '../components/MainHead.astro';
import Header from '../components/Header.astro';
import Intro from '../components/Intro.astro';
import Skills from '../components/Skills.astro';
import Work from '../components/Work.astro';
import Journey from '../components/Journey.astro';
import Testimonials from '../components/Testimonials.astro';
import Footer from '../components/Footer.astro';
---
<html lang="en">
<head>
<MainHead />
</head>
<body>
<Header />
<main>
<Intro />
<Skills />
<Work />
<Journey />
<Testimonials />
<Footer />
</main>
</body>
</html>
<style lang="scss">
main {
padding-top: 150px;
width: 100%;
max-width: 700px;
margin: 0 auto;
}
</style>
MainHead
component in the head of our structure. Let's see how that component looks like.--------
import site from "../data/site.json";
const {title, description} = site;
--------
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{title}</title>
<meta name="Description" content={description}>
<link rel="stylesheet" type="text/css" href="/global.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/devicons/[email protected]/devicon.min.css">
<link rel="icon" href="/favicon.ico" />
Skills.astro
component, we can define the data we need:--------
import site from "../data/site.json";
import SkillItem from './SkillItem.astro';
const title = `These are skills I've mastered over the years`;
const comfortable = `Skills I'm super comfortable with`;
const mastering = `Skills I'm mastering`;
const {skills} = site;
--------
<div class="skills">
{skills.comfortable.map((item) => (
<SkillItem item={item} />
))}
</div>
<div class="skills">
{skills.mastering.map((item) => (
<SkillItem item={item} />
))}
</div>
comfortable
and mastering
arrays.--------
const { item } = Astro.props;
--------
<div class="skills-item tooltip-container">
<span class="tooltip">{item.name}</span>
<i class={`devicon-${item.icon}-${(item.type?item.type:'plain')}`}></i>
</div>
<style lang="scss">
.skills-item {
background: #fff;
padding: 10px;
margin: 5px;
border-radius: 5px;
display: flex;
align-items: center;
justify-content: center;
i {
color: var(--color-purple);
font-size: 2rem;
}
}
</style>
Astro.props
.--------
import site from "../data/site.json";
const {nav} = site;
--------
<header id="header">
<ul>
{nav.map((item) => (
<li>
<a href={item.link} target={item.target} rel="noopener noreferrer">{item.name}</a>
</li>
))}
</ul>
</header>
<script type="text/javascript">
const header = document.getElementById("header");
window.onscroll = function() {
if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {
header.classList.add("active");
} else {
header.classList.remove("active");
}
};
</script>
assets
folder.<img src="/assets/image.jpg" />