Skip to content

Instantly share code, notes, and snippets.

View kentcdodds's full-sized avatar
🤓
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
@kentcdodds
kentcdodds / README.md
Created October 11, 2025 04:13
Unofficial, AI-generated @remix-run/dom and @remix-run/events docs

@remix-run/events and @remix-run/dom Documentation

NOTE: this was generated by Cursor from within the Remix demo using the following prompt:

Please use the example code in @public/ and the types definitions to write documentation for @remix-run/events and @remix-run/dom and stick it in a markdown file in the root of this repo.

This documentation covers two core Remix 3 packages: @remix-run/events for declarative event handling and @remix-run/dom for creating reactive UI components.

Table of Contents

@kentcdodds
kentcdodds / README.md
Last active June 2, 2025 17:03
epicshop notifications

Epicshop Notifications

This gist provides notifications for the Epicshop platform. Notifications are loaded on demand and shown to users based on specific criteria.

How Notifications Work

Notifications are defined in the notifications.json5 file. Each notification is an object with the following properties:

@jacobparis
jacobparis / mcp.server.ts
Created April 1, 2025 03:09
React Router MCP Server
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js"
import { Socket } from "net"
import { Readable } from "stream"
import { IncomingMessage, type ServerResponse } from "http"
import {
subscribeToChannel,
unsubscribeFromChannel,
publishMessage,
} from "../redis.server.js"
@jacob-ebey
jacob-ebey / deferred-overview.md
Last active February 28, 2025 05:42
Deferred Overview

Remix Deferred

Remix Deferred is currently implemented on top of React's Suspense model but is not limited to React. This will be a quick dive into how "promise over the wire" is accomplished.

SSR + Hydration

It isn't rocket science, but a quick recap of how frameworks such as react do SSR:

  1. Load data
  2. Render the app
// TODO: make `pages` optional and measure the div when unspecified, this will
// allow more normal document flow and make it easier to do both mobile and
// desktop.
import {
createContext,
useCallback,
useContext,
useEffect,
useMemo,
useRef,
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
kentcdodds / cachified.ts
Last active April 19, 2023 04:54
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.
type CacheMetadata = {
createdTime: number
maxAge: number | null
expires: number | null
}
function shouldRefresh(metadata: CacheMetadata) {
if (metadata.maxAge) {
return Date.now() > metadata.createdTime + metadata.maxAge
}
@kentcdodds
kentcdodds / useOnRead.tsx
Last active June 9, 2021 04:24
How I determine whether you've read a blog post.
function useOnRead({
parentElRef,
onRead,
enabled = true,
}: {
parentElRef: React.RefObject<HTMLElement>
onRead: () => void
enabled: boolean
}) {
React.useEffect(() => {
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();
app.use(compression());

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