Stephen Bradshaw

Portfolio Site

Stephen Bradshaw

Tech choices

Framework: this site would be a good candidate for using static-site-generation (SSG), for example using Next.js, because the site is relatively small and the content won't change often. However, in the end I decided to go with a "standard" React app, as I needed to get up-and-running quickly. I might convert the site to SSG later.

Styling: I went with Styled Components. I love how easy it is to add theming and to adapt styles using props. The drawback is a small performance hit compared to pure CSS, because the JS has to be downloaded first.

TypeScript: Although TypeScript makes the most sense for larger projects, I decided to use it here to help consolidate my knowledge. I also love having code completions 😍.

Contentful: For me, separating content from code using a CMS is a no-brainer, making it easier to make changes, and providing the ability to use a rich text editor to write content.

The Contentful JavaScript SDK also works really well with TypeScript. Using the contentful-typescript-codegen package, you can generate types matching your contentful schema - in my case I just have to do npm run codegen to sync the two up.

When fetching data, you pass the type the generic provided on getEntries(), which ensured type safety for the returned data. For example, to get all entries of type project in the de-DE locale:

import {IProjectFields} from "schema/generated/contentful";

const results = await contentfulClient.getEntries<IProjectFields>({
    locale: "de-DE",
    content_type: "project",
});


SVG Animations

I added some cute little line animations:

SVG line animations example

To do this, you first have to set the pathLength in the SVG markup itself`:

<path d="m5.54 ..." pathLength="1"/>

Then, in the CSS, you animate the stroke-dashoffset property:

a {
  path {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    transition: stroke-dashoffset 0.5s ease;
  }
  :hover {
    path {
      stroke-dashoffset: 0;
    }
  }
}

Et voila! I learnt this from CSS tricks, check out the article for more.