This tutorial will show you how to persist user inputs after form submit in Remix.
- Remix installed
import { index, prefix, route } from "@react-router/dev/routes"; | |
import { camelize, pluralize, singularize } from "inflected"; | |
function createCrud(base = "./views") { | |
/** | |
* Create a CRUD route configuration. | |
* @param name The name of the resource. It will be pluralized for the path. | |
* @param options The options for the crud. | |
* @param options.member Extra routes to add to each member. | |
* @param options.collection Extra routes to add to the collection. |
import Auth0 from "@auth/core/providers/auth0"; | |
import { RemixAuth } from "~/services/auth" | |
import { sessionStorage } from "~/services/session.server"; | |
export let { loader, action } = RemixAuth({ | |
sessionStorage: sessionStorage, // this does nothing yet | |
secret: process.env.AUTH_SECRET ?? "s3cr3t", | |
providers: [ | |
Auth0({ |
This tutorial will show you how to persist user inputs after form submit in Remix.
module.exports = { | |
theme: { | |
screens: { | |
"-2xl": { max: "1536px" }, | |
"-xl": { max: "1280px" }, | |
"-lg": { max: "1024px" }, | |
"-md": { max: "768px" }, | |
"-sm": { max: "640px" }, | |
"sm~md": { min: "640px", max: "768px" }, | |
"md~lg": { min: "768px", max: "1024px" }, |
import { test, expect, describe, beforeAll, afterAll } from "vitest"; | |
import "pptr-testing-library/extend"; | |
import { type App, start } from "test/helpers/app"; | |
import { loader } from "./articles"; | |
import { logger } from "~/services/logger.server"; | |
import type { PrismaClient } from "@prisma/client"; | |
import { createDatabaseClient } from "test/helpers/db"; | |
describe("E2E", () => { | |
let app: App; |
import { renderToStream } from "@react-pdf/renderer"; | |
import ReactDOMServer from "react-dom/server"; | |
import { EntryContext, Headers, RemixServer, Request, Response } from "remix"; | |
import PDF, { loader } from "./pdfs/my-pdf.server"; | |
async function handlePDFRequest(request: Request, headers: Headers) { | |
// get the data for the PDF | |
let response = await loader({ request, context: {}, params: {} }); | |
// if it's a response return it, this means we redirected | |
if (response instanceof Response) return response; |
/* eslint-disable unicorn/prefer-module */ | |
module.exports = { | |
root: true, | |
parser: "@typescript-eslint/parser", | |
plugins: [ | |
"@typescript-eslint", | |
"unicorn", | |
"import", | |
"react", | |
"prettier", |
// create a session storage instance | |
let sessionStorage = createCookieSessionStorage(); | |
// create authenticator instance | |
let authenticator = new Authenticator<User>( | |
sessionStorage | |
); | |
// configure the authenticator to use the Auth0 strategy for sign-in | |
authenticator.use( |
import { randomBytes } from 'crypto'; | |
import * as React from 'react'; | |
import { Request, Session } from 'remix'; | |
import { parseBody, parseParams } from './parse-body'; | |
/** | |
* An error that is thrown when a CSRF token is missing or invalid. | |
* @example | |
* throw new InvalidAuthenticityToken("Can't verify CSRF token authenticity."); | |
* @example |
abstract class Serializer { | |
abstract attributes: string[]; | |
[customAttribute: string]: unknown; // this allow this[attribute] to work so we can use getters to add extra attributes | |
constructor(protected input: Record<string, unknown>) {} | |
private filterAttributes() { | |
return Object.fromEntries( | |
this.attributes.map((attribute) => { |