Skip to content

Instantly share code, notes, and snippets.

working hard to make the world better with software

Kent C. Dodds kentcdodds

working hard to make the world better with software
View GitHub Profile
View remix-magic-auth.tsx
import crypto from "crypto";
import { renderToStaticMarkup } from "react-dom/server";
import createMailgun from "mailgun-js";
import type { ActionFunction, LoaderFunction, Session } from "remix";
import { createCookieSessionStorage, json, redirect } from "remix";
* Before we can do anything, we need to make sure the environment has
* everything we need. If anything is missing, we just prevent the app from
* starting up.
kentcdodds / cachified.ts
Last active Dec 9, 2021
Turn any function into a cachified one. With forceFresh support and value checking (for when the data type changes). This uses redis, but you could change it to use whatever you want.
View cachified.ts
type CacheMetadata = {
createdTime: number
maxAge: number | null
expires: number | null
function shouldRefresh(metadata: CacheMetadata) {
if (metadata.maxAge) {
return > metadata.createdTime + metadata.maxAge
kentcdodds / useOnRead.tsx
Last active Jun 9, 2021
How I determine whether you've read a blog post.
View useOnRead.tsx
function useOnRead({
enabled = true,
}: {
parentElRef: React.RefObject<HTMLElement>
onRead: () => void
enabled: boolean
}) {
React.useEffect(() => {
View server.js
const path = require("path");
const express = require("express");
const compression = require("compression");
const morgan = require("morgan");
const { createRequestHandler } = require("@remix-run/express");
let app = express();

Route Module Pending Component Export

There are two primary approaches to page transitions (ignoring suspense's ditched attempt at a third)

  1. Indefinitely wait on the old screen
  2. Transition immediately to spinners/skeleton

Right now Remix has picked #1, but with a new export to a route module, we could support both.

Today, if you have this, Remix will wait for all data to load before displaying the page


Pure ESM package

The package linked to from here is now pure ESM. It cannot be require()'d from CommonJS.

This means you have the following choices:

  1. Use ESM yourself. (preferred)
    Use import foo from 'foo' instead of const foo = require('foo') to import the package. You also need to put "type": "module" in your package.json and more. Follow the below guide.
  2. If the package is used in an async context, you could use await import(…) from CommonJS instead of require(…).
  3. Stay on the existing version of the package until you can move to ESM.
kentcdodds /
Last active Aug 9, 2022
Function syntaxes supported by TypeScript

The blog post has been written:

TypeScript Function Syntaxes

I'm trying to create examples of all the different ways to write functions and function type definitions in TypeScript.

One requirement is these examples must work with strict mode (noImplicitAny, etc) enabled.

If I'm missing anything, please add comments below with examples. I'll eventually put this into a blog post.

kentcdodds / .gitignore
Last active Jun 8, 2022
This will create a Google Voice "native" app on your computer
View .gitignore
ryanflorence / $post.edit.tsx
Last active Mar 9, 2022
The Anatomy of a Remix Route
View $post.edit.tsx
* The Anatomy of a Remix Route
import { parseFormBody, json, redirect } from "@remix-run/data";
import {
} from "@remix-run/react";

Route Transition API


The goal of the route transition API is to enable suspense-like transition in React Router without using Suspense (much like v1).

On location changes, React Router will continue to send down the old location, activating pending hooks for loading states and optimistic UI, and wait for your Route's preloading hooks to resolve before sending down the new location and updating your app.

This enables you to declare data dependencies on your routes, allowing your route elements to expect data and not need to manage their own loading states.