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
kentcdodds / session.server.ts
Created Nov 18, 2021
Authentication in Remix applications
View session.server.ts
import * as bcrypt from "bcrypt";
import { createCookieSessionStorage, redirect } from "remix";
import { db } from "./db.server";
export type LoginForm = {
username: string;
password: string;
kentcdodds / autofill-feedback-email.js
Last active Jan 11, 2022
I use this to automatically fill in email addresses in feedback forms throughout workshop material
View autofill-feedback-email.js
#!/usr/bin/env node
const path = require('path')
const inquirer = require('inquirer')
const replace = require('replace-in-file')
const isCI = require('is-ci')
const spawn = require('cross-spawn')
const fileGlob = process.argv[2] || 'src/**/*.*'
const files = path.isAbsolute(fileGlob)
View abort-controller.js
function useAbortController() {
const abortControllerRef = React.useRef()
const getAbortController = React.useCallback(() => {
if (!abortControllerRef.current) {
abortControllerRef.current = new AbortController()
return abortControllerRef.current
}, [])
React.useEffect(() => {
kentcdodds / package.json
Last active Dec 11, 2021
setup script for my workshops
View package.json
"name": "workshop-setup",
"version": "1.0.0",
"description": "This is the common setup script for most of my workshops",
"bin": "./setup.js"
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 / cell.tsx
Created Oct 18, 2021
A real-world example of the prop getters pattern
View cell.tsx
function Cell({
row: {values: user},
column: {id: propertyName},
}: {
value: string
row: {values: User}
column: {id: string}
}) {
View scroll-restoration.tsx
import * as React from 'react'
import {useLocation} from 'react-router-dom'
import {useTransition} from '@remix-run/react'
import {useBeforeUnload} from 'remix'
import {useSSRLayoutEffect} from './misc'
let firstRender = true
let positions: {[key: string]: number} = {}
const SESSION_STORAGE_KEY = 'kody_scroll_positions'
kentcdodds / package.json
Last active Dec 8, 2021
Validates that the versions of tools specified in `engines` in the package.json are installed on the machine.
View package.json
"name": "workshop-computer-validator",
"version": "1.0.0",
"description": "I use this to validate people's computers have the proper versions of node and npm installed for a workshop",
"bin": "./validate-system.js",
"dependencies": {
"semver": "7.1.3"
View kit.log
[2021-11-18 18:49:03.381] [info] Protocols Prepared
[2021-11-18 18:49:03.386] [info] Tray created
[2021-11-18 18:49:03.389] [info] Shortcuts Assigned
[2021-11-18 18:49:03.398] [info] Prompt window created
[2021-11-18 18:49:03.399] [info] Tick started
[2021-11-18 18:49:03.399] [info] is ready...
[2021-11-18 18:49:03.406] [info] SHORTCUTS DB CHANGED: /Users/kentcdodds/.kit/db/shortcuts.json
[2021-11-18 18:49:03.411] [info] Registered CommandOrControl+; to /Users/kentcdodds/.kit/main/index.js
[2021-11-18 18:49:03.412] [info] Registered CommandOrControl+Alt+Control+C to /Users/kentcdodds/.kenv/scripts/cloudinary-upload.js
[2021-11-18 18:49:03.413] [info] Registered CommandOrControl+Alt+Control+O to /Users/kentcdodds/.kenv/scripts/daily-story.js
kentcdodds /
Created Nov 22, 2021
Headers and caching section removed from the Remix Tutorial because it was too long.

Headers and Caching

Caching is a big subject and it can get pretty complicated. Luckily, the browsers have done all the really hard work for us and we just need to #useThePlatform.

There are three types of caches you'll likely deal with in Remix applications:

  1. Application-level caches that you implement in your own code.
  2. Browser caches you can control through the Cache-Control header.
  3. CDN caches you also can control through the Cache-Control headers.