About NextJS Data Fetching and LEGO

2021-03-06

This page is based on NextJS, a web framework to build React-based applications. NextJS allows to pre-render entire web pages, essentially acting as a static site generator similar to Hugo or Jekyll.

The goal of this mini project was to have a table-based overview of all sets I currently own and may want to get in the future. If you want to see the end result, find it here. For populating it with data, I created a JSON file with the following structure:

{
    "collection": [...],
    "watchlist": [...]
}

Both keys contain a list of lego set numbers which uniquely identify a given set. Based on this source-of-truth file, additional metadata is retrieved from Rebrickable. Specifically, this is achieved by using getStaticProps inside the NextJS page to load the JSON file and fetch set information from the API.

Because API access to Rebrickable requires authentication, the API key is stored in .env.local which is automatically loaded by NextJS. When building the website for publication using Gitlab CI, the key is passed as environment variable to the runner.

Rebrickable returns set information in the following JSON format.

{
    "set_num": "92176-1",
    "name": "NASA Apollo Saturn V",
    "year": 2020,
    "theme_id": 576,
    "num_parts": 1969,
    "set_img_url": "https://cdn.rebrickable.com/media/sets/92176-1/75029.jpg",
    "set_url": "https://rebrickable.com/sets/92176-1/nasa-apollo-saturn-v/",
    "last_modified_dt": "2021-01-04T10:03:48.361554Z"
}

Notably, it provides an image URL which I wanted to use to render a small thumbnail along with the rest of the information. Unfortunately, the URL only contains a full-scale image which would require me to render my own thumbnails. After some digging in the client-side source code of the Rebrickable website, I found that I could conveniently use their thumbnail endpoint instead of using the full-scale image url provided via API.

Using some JavaScript, we rewrite the provided set_img_url to retrieve the corresponding thumbnail instead.

let imgName = set["set_img_url"].split('/').pop()
let setNumber = set["set_num"]
let thumbURL = `https://cdn.rebrickable.com/media/thumbs/sets/${setNumber}/${imgName}/28x28p.jpg`

With this URL, we can embedd a tiny preview of what the set looks like in our table without fetching unnecessarily big image files. Again, feel free to check out the final result and let me know what sets I should consider in the future!