Back to cookbook

AI Prompt to Build a React Authentication Flow With Protected Routes

0 views Updated

Make this prompt yours

Share

This AI prompt for a React authentication flow generates the pieces a typical app needs to gate pages behind a login: a login form, an auth context that tracks the current user and token, and a protected-route wrapper that redirects unauthenticated users. It's aimed at frontend developers wiring up auth against an existing backend API who want a consistent starting structure instead of assembling it from scattered tutorial snippets.

The prompt separates concerns the way a real app should: a context provider owns the session state and exposes login/logout functions, while a ProtectedRoute component checks that state and redirects to a login page when there's no valid session, rather than letting protected pages render first and flash their content. It also asks the model to handle the loading state while the session is being verified on page load, which is the detail most quick auth examples skip and that causes a visible flash of protected content before redirect.

Because this kind of prompt produces several interrelated files at once, running the filled-in version through Prompt Optimizer in its Coding mode first can tighten the constraints around state shape and error handling before you spend a generation cycle on it.

Prompt template

Make this prompt yours

prompt-template
296 tokens
ROLE You are a senior React developer building a reusable authentication flow. CONTEXT Framework: [REACT_VERSION, e.g. React 18] Routing library: [ROUTING_LIBRARY_AND_VERSION, e.g. React Router v6] Backend auth endpoints: [LOGIN_ENDPOINT], [LOGOUT_ENDPOINT], [SESSION_CHECK_ENDPOINT] Token storage method: [TOKEN_STORAGE_METHOD, e.g. httpOnly cookie set by the server] Styling approach: [STYLING_APPROACH, e.g. Tailwind CSS] TASK Generate the following, using functional components and hooks: 1. An AuthContext and AuthProvider that exposes the current user, a loading flag, and login/logout functions. 2. A login form component that calls the login function and displays validation and API errors. 3. A ProtectedRoute component that redirects unauthenticated users to [LOGIN_ROUTE_PATH], preserving the originally requested URL for post-login redirect. 4. On initial app load, verify any existing session before rendering protected routes, showing a loading indicator during the check. CONSTRAINTS - Do not render protected page content until the session check has completed. - Handle network and 401 errors from the auth endpoints gracefully, with user-facing messages. - Keep components small and composable; do not put API calls directly inside UI components. OUTPUT FORMAT Provide each file separately with a filename comment at the top, followed by a 2-3 sentence summary of how the pieces connect together.

Want it sharper? Optimize this prompt with Prompt Optimizer, check it with the Prompt Debugger or shorten it with the Token Optimizer.

Example input

example-input
52 tokens
Framework: React 18 Routing library: React Router v6 Backend auth endpoints: POST /api/login, POST /api/logout, GET /api/session Token storage method: httpOnly cookie set by the server Styling approach: Tailwind CSS

Example output

example-output
448 tokens
// AuthContext.jsx
import { createContext, useContext, useEffect, useState } from 'react';
const AuthContext = createContext(null);
export function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('/api/session', { credentials: 'include' })
.then((res) => (res.ok ? res.json() : null))
.then((data) => setUser(data))
.finally(() => setLoading(false));
}, []);
async function login(email, password) {
const res = await fetch('/api/login', {
method: 'POST',
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password }),
});
if (!res.ok) throw new Error('Invalid credentials');
const data = await res.json();
setUser(data);
}
async function logout() {
await fetch('/api/logout', { method: 'POST', credentials: 'include' });
setUser(null);
}
return (
<AuthContext.Provider value={{ user, loading, login, logout }}>
{children}
</AuthContext.Provider>
);
}
export const useAuth = () => useContext(AuthContext);
// ProtectedRoute.jsx
import { Navigate, useLocation } from 'react-router-dom';
import { useAuth } from './AuthContext';
export function ProtectedRoute({ children }) {
const { user, loading } = useAuth();
const location = useLocation();
if (loading) return <div>Checking session...</div>;
if (!user) return <Navigate to="/login" state={{ from: location }} replace />;
return children;
}

The AuthProvider wraps the app and checks for an existing session cookie on load, exposing user/loading state and login/logout to the rest of the tree. ProtectedRoute reads that context, shows a loading indicator during the initial check, and redirects to /login while remembering the page the user was trying to reach.

When to use it

  • You're starting a new React app that needs login-gated pages and want a clean auth context structure from the start.
  • You're replacing ad-hoc if (user) checks scattered across pages with a single reusable protected-route pattern.
  • You need to handle the brief loading state while a stored token is being verified on app startup.
  • You want a consistent pattern for redirecting unauthenticated users back to login and then on to their original destination after they sign in.

Best practices

  • Specify exactly how the token is stored (memory, httpOnly cookie, or localStorage) since this changes the security model and the code the model should generate.
  • Ask for a loading state in the auth context so protected routes don't render briefly before a redirect fires on page refresh.
  • Request that the protected-route component preserve the originally requested URL so the user lands there after logging in, not just on a generic home page.
  • Specify your routing library version (React Router v6 vs. v7, for example) since the redirect and route-nesting APIs differ between versions.

Common mistakes

  • Not specifying token storage, which often results in plain localStorage being used by default even when that's not appropriate for the app's security needs.
  • Skipping the loading state, causing protected content to flash on screen before the redirect to login happens.
  • Forgetting to ask for logout behavior that clears both the stored token and any cached user data in the context.
  • Not stating the routing library and version, leading to generated code that mixes APIs from different React Router versions.

FAQs

How do I keep a user logged in after a page refresh?

Store the session server-side behind an httpOnly cookie, then call a session-check endpoint on initial app load to restore the user into your auth context before rendering protected routes.

Should I store the auth token in localStorage or a cookie?

An httpOnly cookie set by the server is generally safer since it isn't readable by JavaScript, which reduces exposure to XSS; localStorage is simpler but should be avoided for sensitive tokens if you can use cookies instead.

How do I redirect a user back to the page they wanted after login?

Have the protected route pass the current location in the redirect state when sending the user to the login page, then read that state after a successful login to navigate them to their original destination.

Does this pattern work with Next.js instead of React Router?

The same separation (auth context, loading state, redirect on missing session) applies, but Next.js typically handles the redirect in middleware or a layout component instead of a client-side ProtectedRoute wrapper.

What tool pairs well with this prompt?

Prompt Optimizer — its Coding mode is useful for tightening the constraints around state shape and error handling in a multi-file prompt like this before you spend a generation cycle on it.

Found this prompt useful? Share it.

Share

More in React Prompt Recipes

React Prompt Recipes

AI Prompt to Turn a Design Screenshot into a React Component

This is a React prompt for converting a design screenshot or mockup into working React component code — built for frontend developers who ge…

ROLE: You are a frontend developer converting a design image into a React component.

CONTEXT: I'm attaching a design screenshot/mockup. Tech stack: [REACT VERSION, STYLING APPROACH e.g. Tailwind/CSS Modules/styled-components, COMPONENT LIBRARY IF ANY]

TASK:
1. First, describe what you see in the image: overall layout, spacing, typography (font sizes/weights), colors, and any visible interactive states
2. Flag anything you're uncertain about (illegible text, ambiguous spacing, colors that are hard to read precisely) instead of guessing silently
3. Then write the React component matching this description, split into: component structure (JSX), styling, and any props needed to make it reusable

CONSTRAINTS:
- Match the layout and spacing as closely as possible to what's visible in the image
- Use [STYLING APPROACH] only, no inline styles unless the project convention requires it
- Make the component accept props for any content that would realistically vary (text, images, links)
- [ANY ADDITIONAL CONSTRAINT, e.g. must be accessible, must support dark mode]

OUTPUT FORMAT:
1. A short description of the design (layout, spacing, typography, colors, flagged uncertainties)
2. The complete component code in a fenced code block
3. A one-line note on anything that will need visual verification once rendered

Make this prompt yours

React Prompt Recipes

AI Prompt to Build an Accessible React Modal Component

This prompt generates an accessible React modal component , built for frontend developers who need a dialog that actually works with keyboar…

ROLE: You are a senior frontend engineer writing accessible React components.

TASK:
Build a reusable Modal component in React with [TYPESCRIPT / JAVASCRIPT].

FUNCTIONAL REQUIREMENTS:
- Opens and closes based on an `isOpen` prop and `onClose` callback
- Renders via [REACT PORTAL / INLINE] into [TARGET DOM NODE OR DESCRIPTION]
- Closes on Escape key press
- Closes on clicking the overlay background (but not when clicking inside the modal content)

ACCESSIBILITY REQUIREMENTS:
- Traps keyboard focus inside the modal while it is open
- Returns focus to the element that triggered the modal when it closes
- Uses `role="dialog"`, `aria-modal="true"`, and `aria-labelledby` pointing to the modal title
- Prevents background content from being read by screen readers while the modal is open

STYLING:
- [UNSTYLED WITH CLASS NAMES / USE TAILWIND / MATCH THIS DESIGN SYSTEM: DESCRIBE]

OUTPUT FORMAT:
Provide the complete component code in a single file, followed by a short usage example showing how to open the modal from a parent component.

Make this prompt yours

React Prompt Recipes

ChatGPT Prompt to Build a React Data Table With Sorting, Filtering, and Pagination

This ChatGPT prompt is for frontend developers who need a working React data table component — the kind with sortable columns, a search/filt…

ROLE:
You are a senior frontend engineer who writes clean, accessible React components.

CONTEXT:
I need a React component called [COMPONENT_NAME] that displays a data table for the following data shape:
[DESCRIBE_DATA_SHAPE_E.G._ARRAY_OF_OBJECTS_WITH_FIELDS_AND_TYPES]

REQUIREMENTS:
- Columns: [LIST_COLUMN_NAMES_AND_WHICH_ARE_SORTABLE]
- Sorting: clicking a sortable column header toggles ascending/descending order, with a visible indicator of current sort state
- Filtering: a single search input that filters rows by [SPECIFY_WHICH_FIELDS_TO_MATCH], case-insensitive
- Pagination: [NUMBER] rows per page, with previous/next controls and a current page indicator
- Empty states: show a clear message when the data array is empty, and a separate message when a filter returns no results
- Accessibility: sortable headers must be keyboard-operable and expose their sort state to screen readers
- Styling approach: [SPECIFY_E.G._TAILWIND_CLASSES_OR_PLAIN_CSS_MODULES]

OUTPUT FORMAT:
Return the complete component code in a single code block, followed by a short list of any assumptions you made about data or behavior that I didn't specify.

Make this prompt yours