Updated
Portfolio Website
I decided early on in developing the website for my portfolio that I wanted much of its look and feel to be dynamic - as in any previews or visualizations of the technologies used can change based on the content I add into the CMS.
An example of this is the homepage - which shows a laptop and cellphone displaying slideshows of the projects I've developed. I can add a new project into the CMS and without any code updates or production moves, the homepage slideshows will update with that new project. Each project can have a mobile and a desktop view that will then display once pulled in from Sanity.
<div className="p-2 lg:p-6 flex flex-col items-center h-[70vw] lg:h-[30rem] cursor-pointer transition-transform hover:scale-105 duration-200">
<Laptop className="max-w-[100%]">
<ContainedSlideshow>
{desktopImages.map((image) => (
<SanityImage
source={image}
key={image.asset._ref}
layout="fill"
/>
))}
</ContainedSlideshow>
</Laptop>
<Smartphone className="max-w-[20%] -translate-y-[110%] -translate-x-[180%]">
<ContainedSlideshow>
{mobileImages.map((image) => (
<SanityImage
source={image}
key={image.asset._ref}
layout="fill"
/>
))}
</ContainedSlideshow>
</Smartphone>
</div>
export const getStaticProps: GetStaticProps = async () => {
const technologyQuery = `
*[_type == "technology"] | {
logo,
slug
}
`;
const projectQuery = `
*[_type == "project"] | order(publishedAt desc) {
title,
slug,
desktopView,
mobileView
}`;
const technologiesResponse: Promise<Technology[]> =
sanityClient.fetch(technologyQuery);
const projectsResponse: Promise<Project[]> =
sanityClient.fetch(projectQuery);
const technologies = await technologiesResponse;
const projects = await projectsResponse;
return {
props: { technologies, projects },
};
};
The blog pages for each project, technology, and blog entry are displayed using the TailwindCSS plugin tailwindcss/typography with the "Prose" class. This provides nicely formatted posts while requiring very little additional configuration.
One of the more difficult things to implement in the posts was syntax highlighting and code blocks. Given that this is a portfolio for software development, it wasn't really fitting that all the code would be displayed as images, so I set out to find a good syntax highlighter that plays nicely with TailwindCSS and Sanity. It was not easy to get it functioning correctly, but I finally settled on using react-syntax-highlighter
with Highlight.js which provided the customization options I needed for the Sanity/PortableText configuration and display of my code.
import SyntaxHighlighter from "react-syntax-highlighter";
import { tomorrowNight } from "react-syntax-highlighter/dist/cjs/styles/hljs";
interface Props {
language: string;
children: React.ReactNode;
}
const Code = ({ language, children }: Props) => {
return (
<SyntaxHighlighter
language={language || "javascript"}
style={tomorrowNight}
>
{children}
</SyntaxHighlighter>
);
};
export default Code;
const components: Partial<PortableTextReactComponents> = {
types: {
...
code: ({ value }) => (
<Code language={value.language}>{value.code}</Code>
),
...
},
...