All skills
sergiodxa avatar

/frontend-react-router-best-practices

@9da9532

React Router performance and architecture patterns. Use when writing loaders, actions, forms, routes, or working with React Router data fetching. Triggers on tasks involving React Router routes, data loading, form handling, or route organization.

Use this Skill: https://skilld.dev/gh/sergiodxa/agent-skills/frontend-react-router-best-practices

This session only. Nothing lands on disk.

rulesloader-action-abort-signal.md

≈683 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Abort Async Work in Loaders and Actions

Use request.signal to abort in-flight async work when the client cancels a navigation.

Why

  • Prevent wasted work when the user navigates away
  • Reduce backend load for requests that will never be used
  • Keep loaders responsive under rapid navigation

Fetch Calls

import { data } from "react-router";

export async function loader({ request }: Route.LoaderArgs) {
  let response = await fetch("https://example.com/api", {
    signal: request.signal,
  });

  return data(await response.json());
}

Parallel Requests

export async function loader({ request }: Route.LoaderArgs) {
  let [a, b] = await Promise.all([
    fetch(urlA, { signal: request.signal }),
    fetch(urlB, { signal: request.signal }),
  ]);

  return data({ a: await a.json(), b: await b.json() });
}

AbortError Handling

export async function loader({ request }: Route.LoaderArgs) {
  try {
    let response = await fetch(url, { signal: request.signal });
    return data(await response.json());
  } catch (error) {
    if (error instanceof Error && error.name === "AbortError") {
      return new Response(null, { status: 204 });
    }
    throw error;
  }
}

Non-Fetch Async Work

If an API doesn't accept an AbortSignal, check manually between steps:

export async function action({ request }: Route.ActionArgs) {
  let first = await doStepOne();
  if (request.signal.aborted) throw new Error("AbortError");

  let second = await doStepTwo();
  if (request.signal.aborted) throw new Error("AbortError");

  return data({ first, second });
}

Database Transactions

If the action touches your database, wrap the steps in a transaction so an abort can roll back partial work:

export async function action({ request }: Route.ActionArgs) {
  return db.transaction(async (trx) => {
    let a = await createA(trx);
    if (request.signal.aborted) throw new Error("AbortError");

    let b = await createB(trx, a.id);
    if (request.signal.aborted) throw new Error("AbortError");

    return data({ a, b });
  });
}

If the action triggers external side effects (fetching other APIs), rolling back may be difficult or impossible — design with idempotency or compensating actions in mind.

Rules

  1. Always pass request.signal to fetch calls in loaders/actions
  2. Handle AbortError explicitly when you catch errors
  3. For non-fetch async work, check request.signal.aborted between steps
  4. Use DB transactions to roll back partial work in actions
  5. Be cautious in actions that trigger side effects on external services

Source: SKILL.md on GitHub

2 warnings16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill provides a comprehensive set of developer guidelines and best practices for building React Router applications. It emphasizes performance, type safety, and security measures like input validation (Zod), safe redirects, and CSRF protection (Sec-Fetch). No malicious code, obfuscation, or data exfiltration patterns were detected.

  • Socket16d

    1 alert: gptSecurity

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer7mo

    56/56 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 9da9532. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Dormantupdated 8 months ago

README badge

README badge for sergiodxa/agent-skills/frontend-react-router-best-practices