| name | develop |
| description | Expert Remix/React/TypeScript SSR developer for MMO FES External Frontend. Use when: implementing features, fixing bugs, refactoring code, researching codebase, planning solutions, writing production code. Covers Remix patterns, GOV.UK components, i18next, CSRF, progressive enhancement. |
| license | OGL-UK-3.0 |
| metadata | {"author":"mmo-fes","version":"1.0"} |
External Frontend — Developer Skill
Expert software engineer for the MMO FES External Frontend. Reads the codebase, researches, plans, reasons, writes production-ready code following Remix/GOV.UK patterns.
When to Use
- Implementing new routes, loaders, or actions
- Building GOV.UK-styled components with i18next translations
- Setting up MSW handlers for new API endpoints
- Refactoring or restructuring Remix routes
- Any production code writing task
Workflow
Before Making Changes
- Search codebase for similar route patterns and components
- Check existing MSW handlers to understand API mocking patterns
- Review
app/types/tests.ts for existing test case IDs
- Read
app/urls.server.ts for API endpoint definitions
During Implementation
- Follow all mandatory rules from the auto-loaded instruction files (
react-remix.instructions.md, typescript.instructions.md)
- Always add
setApiMock(request.url) as the first line in loaders (for test mode)
- Provide both English and Welsh translations — never leave Welsh as TODO
After Implementation
- Run build:
npm run build
- Run lint:
npm run lint
- Verify no TypeScript errors in problems panel
- Invoke the
/unit-tests skill to set up MSW handlers and Cypress tests
- Review git diff to ensure no accidental changes
Project Conventions
Route Pattern (Flat Structure)
export const loader: LoaderFunction = async ({ request }) => {
setApiMock(request.url);
const csrf = createCSRFToken();
const session = await getSessionFromRequest(request);
session.set("csrf", csrf);
const data = await fetchFromOrchestration(request);
return json({ csrf, data }, session);
};
export const action: ActionFunction = async ({ request }) => {
const form = await request.formData();
const isValid = await validateCSRFToken(request, form);
if (!isValid) return redirect("/forbidden");
};
CSRF Protection
const { csrf } = useLoaderData<typeof loader>();
<SecureForm method="post" csrf={csrf}>
{/* form fields */}
</SecureForm>
Bilingual i18next
const { t } = useTranslation(['namespace']);
GOV.UK Component Usage
- Use
govuk-* class names — never create custom CSS if GOV.UK provides the component
- Use
data-cy or data-testid attributes for test selectors
- Ensure progressive enhancement — forms must work without JavaScript
Server-Only Code
- Server logic in
*.server.ts files — never import in client code
- API URLs centralized in
app/urls.server.ts
- HTTP client in
app/communication.server.ts
Anti-Patterns
Mandatory rules in the instruction files also apply. The items below are additional anti-patterns specific to this skill:
- Forgetting
setApiMock(request.url) in loaders — breaks test mode
- Leaving Welsh translations as TODO placeholders
- Creating custom CSS when GOV.UK Frontend provides the component
- Using nested route directories instead of flat route structure
- Importing
.server.ts modules in client-side code