Skip navigation
Tyssen Design — Brisbane Freelance Web Developer
(07) 3300 3303

First React-ions

By John Faulds /

I recently dipped my toes into the React/Next.js waters for the first time to build a little personal project. I wrote about how I used AI to help me with that recently, and I'll do another post about the project in more depth soon. For this post though, I wanted to write about a few of the gotchyas I encountered while working on the project that I thought it might be useful to document in case others run into similar problems.

Typescript is the default for Next.js projects created with create-next-app

create-next-app defaults to using Typescript

This probably won't be a problem for a lot of people, those who are already quite familiar with javascript and its frameworks. But for me, I hadn't used either React or Typescript (TS) before and found it difficult to learn both at the same time.

This is not something I would've ordinarily done. But when you set up a Next.js project using npx create-next-app@latest it asks you whether you want to use TS and it defaults to Yes, and as I tend to stick to defaults when trying something new, that's what I did.

(By the way, you'll also need to be running Node.js version ≥18.18 when running create-next-app otherwise you'll get errors like SyntaxError: Unexpected token ‘??=’ at wrapSafe (internal/modules/cjs/loader.js:1001:16).)

Using TS wasn't a problem initially, I was working away and everything was working fine in dev mode. But then I got to a point where I needed to run a production build to test a theory and that's when my lack of knowledge ground things to a halt. It was probably more my impatience at wanting to move forward with the initial problem, but I decided to remove the TS dependencies. 

I'll probably come back to it one day, but for a small personal project that I'll only ever be the one to work on, there didn't seem much need to be using TS anyway.

Problems verifying SSL certificates when developing locally

I use DDEV for my local development environment and when trying to run npm run dev initially, I was getting errors fetching the API because of UNABLE_TO_VERIFY_LEAF_SIGNATURE. Node couldn't verify the certificates that DDEV uses. Luckily, the fix was pretty simple (once I'd found it). I updated my dev script in package.json to “dev”: “NODE_TLS_REJECT_UNAUTHORIZED=0 next dev”.

Use the correct prefix for .env variable names

And speaking of production builds, this is another thing that tripped me up. I was using Craft CMS in headless mode as the data source for my project and things were working fine in dev mode, but when I tried to do a production build, I was getting errors about the API I'd created being not found.

It turns out that any variables that are required to be read by Next.js need to have a NEXT_PUBLIC_prefix on them. I'd created variables for CRAFT_CMS_GRAPHQL_ENDPOINT and CRAFT_CMS_GRAPHQL_TOKEN for connecting to and authorising the API I'd created in Craft and they worked fine in dev mode, but when doing a production build, the project wouldn't connect to the API anymore. Adding NEXT_PUBLIC_, e.g. NEXT_PUBLIC_CRAFT_CMS_GRAPHQL_ENDPOINT was the solution.

The docs say:

By default, environment variables are only available on the server. To expose an environment variable to the browser, it must be prefixed with NEXT_PUBLIC_. However, these public environment variables will be inlined into the JavaScript bundle during next build.

Working with remote images

If you're using Next's built-in <Image> component and your images are going to be stored on a CDN and not on your local file system that React has access to, you'll need to update your next.config file. In my case, I was working with images stored on Cloudfront through Amazon S3.


images: {
  remotePatterns: [
    {
      protocol: 'https',
      hostname: 'xxxxxxxxx.cloudfront.net',
      port: '',
      pathname: '/folder-name/**',
    },
  ],
},
				
Code for working with remote images to be added to next.config

It's also worth pointing out that if you're not running your own Node server in production and instead exporting static assets like I was with this project, then you won't be able to use the <Image> component and instead will need to fall back on the standard HTML <img> tag and build it out manually. 

Make sure to update your schemas

This is more to do with Craft CMS than React or Next but it's something that had me scratching my head for a while. I'd created my fields, asset volumes, and channels in Craft and had added them to my schema. I was using Amazon S3 with Cloudfront for storing assets, images, MP3s and CSVs, but then decided it'd be better if the CSVs were stored on the local file system. So I added a new asset volume, and uploaded files to the field but couldn't work out why no data was being returned when previewing the query using graphiql. I eventually worked out it was because I'd forgotten to update the schema to include the new asset volume.

Don't forget to update your schemas!

How do you do on-the-fly Craft image transforms if you can't use Craft tags in your templates?

Because I was working in headless mode which disables all front-end routes for Craft, I couldn't create on-the-fly image transforms in my templates the way I usually would. 

I could've defined my transforms in the control panel, but I guess it's because I'm more used to using plugins like Imager to do on-the-fly transforms, that I don't automatically go for that option.

The Craft docs explain how you can do that in GraphQL, but what if you want to output different sizes for responsive images? You can't do different transforms on the same field by calling the field by its handle but you can create aliases for the field and do the different transforms on those. With the code below, cover is the field name, and cover1x and cover2x are the aliases. 


cover2x: cover {
    url(width: 300, height: 300)
}
cover1x: cover {
    url(width: 150, height: 150)
}
				

Using the Execute Query button in graphiql (the one that looks like a play button) will not only show you a preview of the data that will be returned by the query but it will actually perform the image transform too, even if the source assets are stored on a remote server like S3. So you can pre-render your image transforms from the Craft dashboard without having to hit any front-end templates.

These are just a few of the little bumps I ran into when working on my first React/Next.js/Craft headless project. Once I knew what the actual problem was, they were fairly easy to fix but in some cases it took a while to fully understand what the problem was. Hopefully by documenting them here, if others face similar issues, this might help them fix them quickly too.