# Routefence > Audit the server/client boundary and data flow of one Next.js App Router route before it ships - does a Server Component call a hook or take an onClick, does a function or a database client cross into the browser, are params, searchParams, cookies() and headers() awaited on Next.js 15+, can anyone call its Server Actions, are its redirects swallowed - then fix it. The free check runs in the browser and uploads nothing: it lexes the pasted .tsx/.ts/.jsx/.js files (plus package.json for the Next.js version), finds every function, component, export, import and JSX tag, resolves the imports between the pasted files and follows 'use client' through them to know what renders on the server and what ships to the browser, and runs 17 deterministic checks drawn from App Router practice. The paid audit rates boundaries, data, mutations and conventions, confirms or dismisses every flag and gives exact before/after edits per finding; the paid fix lane writes the whole fixed file(s) and a changes list tied to the flags. The page checks every quote and line against the paste, applies every edit and file back into the paste and re-runs its checks, and calls out a reply that repeats a credential from the paste. App: https://routefence.skillsafe.ai/ API tutorial: https://routefence.skillsafe.ai/api.html ## Input - The files pasted into one box, each introduced by a `// file: ` line (`app/products/[id]/page.tsx`, `components/AddToCart.tsx`, `package.json`); dropped files or a dropped route folder are joined that way automatically (node_modules and .next skipped). A paste with no file line is read as one file (app/page.tsx). - Nothing is built or run: every flag is a reading of the text, with the file and line it points at. Strings, template literals, regex literals and comments are lexed out first, so a string that mentions useState( is never a finding. Imports are resolved between pasted files (relative paths and the @/ alias), so a component is known to render on the server, to be bundled for the browser, or both. - Whether a component imported from a file that was not pasted is a Client Component is outside the check (NX-18 says so); so are next.config, middleware and the parent layouts. next build and next lint stay the ground truth. ## Flags the free check raises - NX-01 (high): useState, useEffect, useRef, useContext, useTransition, useOptimistic, useActionState, next/navigation hooks, an on* handler on a DOM element, or window/document/localStorage in a file that renders on the server; one flag per file with every line. - NX-02 (high): error.tsx or global-error.tsx without 'use client'. - NX-03 (medium): 'use client' or 'use server' that is not the first statement of the file (or, for 'use server', of an async function body) - an ordinary string. - NX-04 (high): a 'use client' file that imports a Node built-in, a database client, next/headers, server-only, or a pasted module that pulls one of these in. - NX-05 (high): an exported async component in a Client Component. - NX-06 (high): a function (arrow, function expression or a local function that is not a Server Action) passed as a prop from a server file into a pasted 'use client' component. - NX-07 (high on Next.js 16, medium on 15, low when the version is unknown, none on 14): params or searchParams read or destructured without await in a page, layout, route handler or generateMetadata. - NX-08 (same grading): cookies(), headers() or draftMode() from next/headers called without await. - NX-09 (high, next/head medium): next/router, next/head, getServerSideProps, getStaticProps, getStaticPaths or getInitialProps inside app/. - NX-10 (high, or low when merely ignored): metadata or generateMetadata exported from a 'use client' file, both exported from one file, or exported where Next.js never reads it. - NX-11 (medium; high when the action is not async): a Server Action ('use server' file export or inline 'use server') that writes data with no authorization call in its body. - NX-12 (low): a Server Action that writes data and never calls revalidatePath, revalidateTag or redirect. - NX-13 (medium): redirect(), permanentRedirect(), notFound(), forbidden() or unauthorized() from next/navigation inside a try whose catch does not rethrow. - NX-14 (medium): route segment config (revalidate, dynamic, runtime, fetchCache, dynamicParams, maxDuration, preferredRegion) that is not a static, valid literal, or dynamic = 'force-static' in a file that reads cookies() or headers(). - NX-15 (high): route.ts and page.tsx in the same segment. - NX-16 (medium; high in the client bundle): a literal credential assigned to a secret-named const, variable or property. - NX-17 (low): 'use client' on a page or layout itself, or fetch in a useEffect of a Client Component. - NX-18 (info): context - counts, the Next.js version, what is outside the check. ## Free extras - Every file with its role (page, layout, route, error, module ...), its directive and where it runs, with the reason; every prop passed into a Client Component and whether it is a value, a function or a Server Action; every read of params, searchParams, cookies() and headers() and whether it is awaited; every Server Action and whether it writes, checks the caller and revalidates; every hook; every segment config value. - Put any audit finding (or all of them, or the fixed files) back into the paste and re-run the check; undo puts the original back. - Exports: the check as Markdown, the flags as CSV, the edited or fixed code, the findings or changes as CSV, the whole result as JSON. ## Paid lanes (the `task` field) - `audit`: `{task, verdict: blocked|needs_work|ready, headline, route, areas: [{area: boundaries|data|mutations|conventions, status: sound|fragile|broken, note}], findings: [{id, flags, file, line, severity, area, title, evidence, why, edits: [{before, after}]}], flag_answers: [{flag, status: confirmed|dismissed, reason}], plan, questions, summary}`. `before` is an exact slice of the file, applied in order. - `fix`: `{task, verdict: fixed|partial, headline, files: [{path, content}], changes: [{file, function, flags, change, why}], verify, open: [{item, flags, reason}], questions, summary}`. `content` is the whole file; at most two new files, never a new page or route; no URL moves unless the note allows it; every export survives (a removed Pages Router export aside). - Run input: `{task, code, facts, note?, audit_handoff?, retry_note?}` - all strings; `facts` is the page's analysis as a JSON string. The audit hands its findings to the fix lane with every edit applied to `code`. - Model: gpt-terra, 10% publisher markup. A run needs a signed-in account; the reservation shown before a run is a hold, and only what the run uses is charged. ## Sources - nextjs-app-router-patterns by Seth Hobson, wshobson/agents (github.com/wshobson/agents, plugins/frontend-mobile-development/skills/nextjs-app-router-patterns), MIT - https://skillsafe.ai/skill/@wshobson/nextjs-app-router-patterns - The checks and the reconciliation are original to this app. Next.js is a trademark of Vercel, Inc.; this app is not affiliated with Vercel.