Rough notes working with Gatsby
Theses are some notes from building this site using Gatsby JS.
I currently use NextJS.
You can find the source code on Github at xpcoffee/emerickbosch.com.
All-the-data with a GraphQL interface
The core of Gatsby is a data-layer with which you can register many different types of data: file metadata, pictures, configuration, application data, etc. You can then query all of the registered data using graphQL queries almost anywhere, including in your build-toolchain and your pages. You can then process the results of those queries (render content, create indexes, etc) and register the processed results with the data-layer so that they can then be queried themselves.
I found the combination of deep access to data in my site and a common query interface to be powerful:
- It made automatic page generation from MDX files very simple.
- I was able to query article files to auto-generate and order a list of articles for my home page.
- I was able to query processing-metadata to auto-generate navigation links for my articles.
MDX
I've never used MDX before this. It's really good. The ability to use components in markdown has made more complex components really simple to add and iterate on. I also find it way easier to read/declarative than most other templating languages that also extra symbols everywhere (parentheses, percentage signs and the like).
I haven't yet tried adding dynamic components to MDX files but I'm excited to try it.
Type-generation for GraphQL queries
The gatsby-plugin-typegen
plugin will read your source, extract GraphQL queries,
compare them against what has been registered with the data-layer and then generate types for them. Follow instructions on thie link to set it up.
Good
- Typesafety for queries, which is the core functionality of Gatsby.
Not-so-good
- This actively modifies your source files during build. I'm not sure if I'm a fan of changes not made by myself popping up in my source files.
- I've had trouble keeping my IDE happy. Generated types don't seem to get picked up quickly; I've frequently run into situations where the IDE complains about non-existent types, but the type definitions are present and contain the type causing the warning. This creates a lot of visual noise during development. It's very likely that I haven't set up my project very well for these types, but it's not obvious to me what's going wrong - mostly my fault, but also partly a lack in dev tooling.
- I find what needs to be generated and how it needs to be made available to the IDE unintuitive. I followed instructions more than understanding what I was doing.
- I've found I've needed to manually add the types in for page-queries (queries who's data automatically gets passed to the component). This is an inconsistent developer experience between automatically getting types and manually needing to add them in depending on the page.
FontAwesome icon generation hack
I've added frontmatter to MDX files where you can specify a FontAwesome icon for the article.
The way this works is a bit hacky. The free-version of FontAwesomeReact component does not accept a string for the icon name. Instead it takes
in a FontAwesome.IconDefinition
, which is a nested object that fully describes the icon. So I needed to turn the string defined in the article
frontmatter into an IconDefinition
.
I do this by using the string as an index on the icon's JavaScript module. That means that the frontmatter
needs to contain the module key of the IconDefinition
I want to use. See also the source.
There's definitely a better way to do this, but it works for now.
SVGs
You can make SVGs accessible as React components using gatsby-plugin-react-svg
.
// in a MDX file
import MySvg from "/images/my-svg.svg";
## An article
Lorem ipsum.
<MySvg />
Lorem ipsum.
Images
I ran into issues importing images directly into documents due to their size. See this issue for more context.
I found using <StaticImage />
to be a simple solution.
Tailwind
Relatively easy to set up using the tailwind guide. However it does strip all styles by default, including those generated by rendering MDX. I had to re-add styles to elements in the global CSS file.
Difficulties
- Markdown tables are a pain to re-style
- The global CSS file in the guide seems to be against best-practice
- Adding this to the pipeline drastically slowed down the dev server startup time (hotloading is fine though)
Deployment
This uses gh-pages
to deploy the site to a branch from which Github pages generates the site.
That means you need 2 core branches: one for development and the other to deploy to (in this project, master
and main
respectively).
This was not intuitive to me.
Open questions/issues
- I'm ignorant at how the datalayer would work at runtime. Right now it's all build-time optimization.
- I'm not confident with GraphQL yet. I find the GraphiQL UI to be difficult to use.