express-like middleware system for your remix loaders and actions

Overview

remix-middleware

Add an express-like middleware stack to your remix loaders and actions!

yarn add remix-middleware
// ./app/middleware.server.ts
export const mdw = createMiddleware();

mdw.use(async (ctx, next) => {
  console.log("middleware activated for", ctx.request.url);
  await next();
  console.log("middleware completed for", ctx.request.url);
});

mdw.use(mdw.routes());
// ./app/routes/posts/index.tsx
import { ActionFunction, LoaderFunction, Form, useLoaderData } from "remix";

import { mdw } from "~/middleware.server";

interface Post {
  id: string;
  title: string;
}

export const loader: LoaderFunction = (props) =>
  mdw.run(props, (ctx) => {
    // ctx.response is where the response object goes
    ctx.response = [
      {
        id: "1",
        title: "My First Post",
      },
      {
        id: "2",
        title: "A Mixtape I Made Just For You",
      },
    ];
  });

export const action: ActionFunction = (props) =>
  mdw.run(props, async (ctx) => {
    const body = await ctx.request.formData();
    const post = { id: "3", title: body.get("title") };
    ctx.response = post;
  });

export default function Posts() {
  const posts = useLoaderData<Post[]>();
  return (
    <div>
      <h1>Posts</h1>
      <div>
        {posts.map((post) => (
          <div key={post.id}>{post.title}</div>
        ))}
      </div>
      <div>
        <Form method="post">
          <p>
            <label>
              Title: <input name="title" type="text" />
            </label>
          </p>
          <p>
            <button type="submit">Create</button>
          </p>
        </Form>
      </div>
    </div>
  );
}

Just have simple JSON that you are returning in a loader like in the example above?

export const loader: LoaderFunction = (props) =>
  mdw.run(
    props,
    mdw.response([
      {
        id: "1",
        title: "My First Post",
      },
      {
        id: "2",
        title: "A Mixtape I Made Just For You",
      },
    ])
  );

remix-auth

We built a middleware that will help interacting with remix-auth more streamlined.

  • isAuthenticated - activates authenticator.isAuthenticated

Setting up remix-auth

// ./app/user.ts
export interface User {
  id: string;
  email: string;
}
// ./app/authenticator.ts
import { Authenticator } from 'remix-auth';
import { sessionStorage } from "./session";
import type { User } from './user';

export const authenticator = new Authenticator<User>(sessionStorage);

Create middleware for your needs

// ./app/middleware.server.ts
import { createMiddleware, AuthCtx, isAuthenticated } from 'remix-middleware';
import { authenticator } from './authenticator';
import type { User } from './user';

// use this middleware for routes that do *not* require authentication
// but you want the user to automatically redirect somewhere
export const unauthed = createMiddleware<AuthCtx<null>>();
unauthed.use(isAuthenticated(authenticator, { successRedirect: '/dashboard' }));
unauthed.use(unauthed.routes());

// use this middleware for routes that *require* authentication
export const authed = createMiddleware<AuthCtx<User>>();
authed.use(isAuthenticated(authenticator, { failureRedirect: '/login' }));
authed.use(authed.routes());

// use this middleware if the route allows both authenticated and
// non-authenticated users
export const mdw = createMiddleware<AuthCtx<User | null>>();
mdw.use(isAuthenticated(authenticator));
mdw.use(async (ctx, next) => {
  if (ctx.user) {
    // ... do something with the user
  } else {
    // ... do something with a non-user
  }
  await next();
});

Now in your routes that require authentication

// in a route that requires auth
import { authed } from '~/middleware.server';

export const loader: LoaderFunction = (props) =>
  authed.run(props, (ctx) => {
    // no user can make it to this point without being authenticated
    // and as a result we now have access to ctx.user which is `User`
    // in this example
    console.log(ctx.user); // { id: '123', email: '[email protected]' }

    ctx.response = { text: `Hi ${ctx.user.email}!` };
  });

Now in your routes that do not require authentication

// in a route that does *not* require auth
import { unauthed } from '~/middleware.server';

// `.run()` doesn't need any middleware, it'll run without it
export const loader = (props) => unauthed.run(props);
You might also like...

Buildable's core open-source offering for actions that makes it easy to collect, centralize and action your backend system activity

Buildable's core open-source offering for actions that makes it easy to collect, centralize and action your backend system activity

What are Action Templates? Action Templates are open-source functions that save developers hundreds of hours when integrating databases, apps and othe

Nov 5, 2022

simple-remix-blog is a blog template built using Remix and TailwindCSS. Create your own blog in just a few minutes!

simple-remix-blog is a blog template built using Remix and TailwindCSS. Create your own blog in just a few minutes!

simple-remix-blog is a blog template built using remix.run and TailwindCSS. It supports markdown and MDX for the blog posts. You can clone it and star

Dec 8, 2022

Instant spotlight like search and actions in your browser with Sugu Search.

Instant spotlight like search and actions in your browser with Sugu Search.

Sugu Search Instant spotlight like search and actions in your browser with Sugu Search. Developed by Drew Hutton Grab it today for Firefox and Chrome

Oct 12, 2022

Zenload - "Load couple loaders and apply transform one-by-one

Zenload Load couple loaders and apply transforms one-by-one. Install npm i zenload -g How to use? With env vairable ZENLOAD: NODE_OPTIONS='"--loader

Jan 25, 2022

Node.js ESM loader for chaining multiple custom loaders.

ESMultiloader Node.js ESM loader for chaining multiple custom loaders. Fast and lightweight No configuration required, but configurable if needed Usag

Sep 12, 2022

Remix enables you to build fantastic user experiences for the web and feel happy with the code that got you there. In this workshop, we'll look at some more advanced use cases when building Remix applications.

💿 Advanced Remix Workshop Remix enables you to build fantastic user experiences for the web and feel happy with the code that got you there. In this

Dec 9, 2022

Remix enables you to build fantastic user experiences for the web and feel happy with the code that got you there. Get a jumpstart on Remix with this workshop.

💿 Remix Fundamentals Build Better websites with Remix Remix enables you to build fantastic user experiences for the web and feel happy with the code

Dec 25, 2022

The Remix version of the fakebooks app demonstrated on https://remix.run. Check out the CRA version: https://github.com/kentcdodds/fakebooks-cra

Remix Fakebooks App This is a (very) simple implementation of the fakebooks mock app demonstrated on remix.run. There is no database, but there is an

Dec 22, 2022

Remix Stack for deploying to Vercel with remix-auth, Planetscale, Radix UI, TailwindCSS, formatting, linting etc. Written in Typescript.

Remix Stack for deploying to Vercel with remix-auth, Planetscale, Radix UI, TailwindCSS, formatting, linting etc. Written in Typescript.

Remix Synthwave Stack Learn more about Remix Stacks. npx create-remix --template ilangorajagopal/synthwave-stack What's in the stack Vercel deploymen

Dec 25, 2022
Comments
  • add github ISSUE_TEMPLATE files

    add github ISSUE_TEMPLATE files

    What is the change?

    Add bug_report.yml & config.yml file to enable Github's form based issue template

    • https://youtu.be/qQE1BUkf2-s?t=23

    Motivation

    • encourage's bug reporter's to put more care into their bug report before submission
    • this may help maintainer's receive more detailed & higher quality bug report's
    • adds helpful tips for user's during the process of creating a bug/issue report

    Demo of Change

    this PR is similar to this one I created here for another repo recently

    • https://github.com/antvis/G6/blob/master/.github/ISSUE_TEMPLATE/bug_report.yml
    opened by cliffordfajardo 4
Releases(0.1.1)
Owner
Eric Bower
We're all in the gutter, but some of us are looking at the stars.
Eric Bower
Zod utilities for Remix loaders and actions.

Zodix Zodix is a collection of Zod utilities for Remix loaders and actions. It abstracts the complexity of parsing and validating FormData and URLSear

Riley Tomasek 172 Dec 22, 2022
Keep your Business Logic appart from your actions/loaders plumbing

Remix Domains Remix Domains helps you to keep your Business Logic appart from your actions/loaders plumbing. It does this by enforcing the parameters'

Seasoned 290 Jan 2, 2023
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
The Frontend of Escobar's Inventory Management System, Employee Management System, Ordering System, and Income & Expense System

Usage Create an App # with npx $ npx create-nextron-app my-app --example with-javascript # with yarn $ yarn create nextron-app my-app --example with-

Viver Bungag 4 Jan 2, 2023
Deploy an Architect project from GitHub Actions with keys gathered from aws-actions/configure-aws-credentials

Deploy an Architect project from GitHub Actions with keys gathered from a specific AWS IAM Role federated by an IAM OIDCProvider. CloudFormation to cr

Taylor Beseda 4 Apr 6, 2022
startupDB is an Express middleware function implementing a high-performance in-memory database

startupDB startupDB is a database designed to create REST APIs. It is implemented as an Express middleware function and allows for easy implementation

Jeroen de Vries 8 Jul 26, 2022
Express middleware for easy OAuth with a variety of providers.

accounted4 Express middleware for easy OAuth2 with a variety of providers. accounted4 is intended to make it easy for developers to add third-party OA

Josh Moore 3 May 7, 2022
Magically create forms + actions in Remix!

Welcome to Remix Forms! This repository contains the Remix Forms source code. We're just getting started and the APIs are unstable, so we appreciate y

Seasoned 321 Dec 29, 2022