RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Configs/Cursor rules/RealistSec/mpa-first-guidelines

Cursor rule

.cursor/rules/mpa-strict-rules.mdc

MPA-First Development Mandate - Strict rules for building performant, resilient Multi-Page Applications

Cursor rules

Quality

66/100

Scores the file, not the repository.

Length

1,828 words

18 headings · 12 code blocks

Repository

10

— · pushed 241 days ago

Last changed

3 days ago

First indexed 3 days ago.
RealistSec/mpa-first-guidelines/.cursor/rules/mpa-strict-rules.mdcRawGitHub
1---
2description: MPA-First Development Mandate - Strict rules for building performant, resilient Multi-Page Applications
3globs:
4 - "**/*.php"
5 - "**/*.html"
6 - "**/*.js"
7 - "**/*.css"
8alwaysApply: true
9---
10 
11# AI Coding Agent Guidelines: The MPA-First Mandate
12 
13## Introduction: Why We Build This Way
14 
15For over a decade, web development has trended towards complex, JavaScript-heavy Single-Page Applications (SPAs). The promise was a slick, "app-like" user experience. The reality, in most cases, has been bloated, fragile, and over-engineered websites that are slow to load, difficult to maintain, and hostile to users and search engines.
16 
17This document outlines a return to a more resilient, performant, and durable web. We are intentionally choosing a **Multi-Page Application (MPA)** architecture. The guiding principle is to **use the platform**. We build upon the native strengths of HTML, CSS, and the browser itself, which have evolved significantly. Modern features like CSS View Transitions and Speculation Rules now provide the fluid user experience that once required megabytes of JavaScript, but without the performance penalty.
18 
19We are choosing simplicity, speed, and maintainability over unnecessary complexity. We build for users and outcomes, not for developer experience (DX) or architectural novelty. JavaScript is a powerful tool for progressive enhancement, not the default foundation for every page.
20 
21---
22 
23## PRIME DIRECTIVE: MPA-Only Architecture
24 
25- You **MUST** create server-rendered, multi-page websites (MPAs). Each distinct page or view must be its own unique file (e.g., `.html`, `.php`) served at a distinct URL.
26- Navigation **MUST** use standard anchor links (`<a href="...">`) that trigger a full page navigation. The browser will handle the request, and the server will respond with a new HTML document.
27- The goal is to produce sites that are fundamentally functional with zero client-side JavaScript. JS should only be used to enhance, not to enable, core functionality.
28 
29### 🚫 BANNED TECHNOLOGIES & PATTERNS
30 
31- **DO NOT** use or reference any Single-Page Application (SPA) frameworks, libraries, or patterns.
32 - This includes, but is not limited to: React, Angular, Vue, Svelte, Next.js, Nuxt.js.
33- **DO NOT** use JSX, TSX, TypeScript-based routing, or any form of client-side routing.
34 
35---
36 
37## Guiding Complex Changes
38 
39When approaching a complex change or refactoring a large file, prioritize clarity and communication:
40 
411. **Outline a Plan:** Before diving in, briefly describe your approach. What is the goal? Which parts of the code will you touch?
422. **Communicate as You Go:** Explain your changes in small, logical steps. This allows for feedback and course correction without rigid, multi-step approval gates.
433. **Focus on Conceptual Changes:** Group your edits logically. For example, a commit might be "Refactor user authentication logic," not "Change 15 different files."
44 
45---
46 
47## Folder Structure
48 
49This structure promotes a clean separation of concerns and follows the Model-View-Controller (MVC) architectural pattern:
50 
51```
52project-root/
53├── public/ # Web root, all publicly accessible files
54│ ├── assets/
55│ │ ├── css/
56│ │ ├── js/
57│ │ ├── images/
58│ │ ├── fonts/
59│ └── index.php # Or index.html
60├── src/ # Application source code
61│ ├── controllers/ # Handles user requests
62│ ├── models/ # Business logic and data interaction
63│ ├── views/ # HTML templates/partials
64│ └── utilities/ # Helper functions, etc.
65├── vendor/ # Composer dependencies
66├── config/ # Configuration files
67├── tests/ # Automated tests
68└── docs/ # Project documentation
69```
70 
71---
72 
73## SEO Best Practices: A Top Priority
74 
75Excellent SEO is not an afterthought; it's a direct result of building a clean, semantic, and performant MPA.
76 
77### 1. The Head is Everything
78 
79Ensure every page has a comprehensive and valid `<head>` section:
80 
81**Example: Detailed `<head>` for a Blog Post**
82 
83```html
84<!DOCTYPE html>
85<html lang="en">
86<head>
87 <meta charset="UTF-8">
88 <meta name="viewport" content="width=device-width, initial-scale=1.0">
89 <title>It's Time for Modern CSS to Kill the SPA | My Awesome Blog</title>
90 <meta name="description" content="Native CSS transitions have quietly killed the strongest argument for client-side routing. Learn how to build faster, simpler websites.">
91 
92 <link rel="canonical" href="https://www.example.com/blog/css-kills-spa">
93 
94 <meta property="og:title" content="It's Time for Modern CSS to Kill the SPA">
95 <meta property="og:description" content="Native CSS transitions have quietly killed the strongest argument for client-side routing. Learn how to build faster, simpler websites.">
96 <meta property="og:type" content="article">
97 <meta property="og:url" content="https://www.example.com/blog/css-kills-spa">
98 <meta property="og:image" content="https://www.example.com/assets/images/blog/og-image-css-spa.jpg">
99 <meta property="og:image:width" content="1200">
100 <meta property="og:image:height" content="630">
101 <meta property="og:site_name" content="My Awesome Blog">
102 
103 <meta name="twitter:card" content="summary_large_image">
104 <meta name="twitter:site" content="@MyAwesomeBlog">
105 <meta name="twitter:title" content="It's Time for Modern CSS to Kill the SPA">
106 <meta name="twitter:description" content="Native CSS transitions have quietly killed the strongest argument for client-side routing.">
107 <meta name="twitter:image" content="https://www.example.com/assets/images/blog/twitter-card-css-spa.jpg">
108</head>
109<body>
110</body>
111</html>
112```
113 
114### 2. Structured Data with JSON-LD
115 
116Embed structured data to help search engines understand your content. This is critical for rich results (reviews, recipes, events, etc.):
117 
118**Example: JSON-LD for an Article**
119 
120```html
121<script type="application/ld+json">
122{
123 "@context": "https://schema.org",
124 "@type": "BlogPosting",
125 "headline": "It's Time for Modern CSS to Kill the SPA",
126 "datePublished": "2025-07-24T09:00:00Z",
127 "dateModified": "2025-07-25T10:30:00Z",
128 "author": {
129 "@type": "Person",
130 "name": "Jono Alderson",
131 "url": "https://www.example.com/authors/jono-alderson"
132 },
133 "image": {
134 "@type": "ImageObject",
135 "url": "https://www.example.com/assets/images/blog/og-image-css-spa.jpg",
136 "width": 1200,
137 "height": 630
138 },
139 "publisher": {
140 "@type": "Organization",
141 "name": "My Awesome Blog",
142 "logo": {
143 "@type": "ImageObject",
144 "url": "https://www.example.com/assets/images/logo.png",
145 "width": 600,
146 "height": 60
147 }
148 },
149 "description": "Native CSS transitions have quietly killed the strongest argument for client-side routing. Learn how to build faster, simpler websites.",
150 "mainEntityOfPage": {
151 "@type": "WebPage",
152 "@id": "https://www.example.com/blog/css-kills-spa"
153 }
154}
155</script>
156```
157 
158---
159 
160## HTML Requirements
161 
162- **Semantic HTML is Mandatory:** Use `<header>`, `<nav>`, `<main>`, `<article>`, `<section>`, `<footer>`, `<aside>`, etc., correctly. This is foundational for accessibility and SEO.
163- **Accessibility (A11Y):** Adhere to WCAG 2.1 Level AA.
164 - All form inputs must have a corresponding `<label>`.
165 - Provide descriptive alt text for all meaningful images (`alt=""` for decorative ones).
166 - Use ARIA roles where semantic HTML isn't sufficient.
167- **Responsive Images:** Use `srcset` and `sizes` to serve appropriately sized images. Use modern formats like WebP or AVIF with a fallback.
168- **Prerender for Instant Navigation:** Use Speculation Rules to make navigation feel instantaneous.
169 
170**Example: Instant Prerendering with Speculation Rules**
171 
172```html
173<script type="speculationrules">
174{
175 "prerender": [{
176 "source": "document",
177 "where": {
178 "href_matches": "/*"
179 },
180 "eagerness": "moderate"
181 }]
182}
183</script>
184```
185 
186---
187 
188## CSS Requirements
189 
190- **Embrace Modern CSS:** Use Flexbox and Grid for layouts. Use Custom Properties for theming and maintainability.
191- **Native View Transitions:** This is our primary tool for creating "app-like" fluid navigation without JavaScript.
192 
193**Example: Cross-Page Fade Transition**
194 
195```css
196/* Add to every page for a simple, elegant fade */
197@view-transition {
198 navigation: auto;
199}
200 
201::view-transition-old(root),
202::view-transition-new(root) {
203 animation: fade-out 0.3s ease-out both;
204}
205 
206@keyframes fade-out {
207 from { opacity: 1; }
208 to { opacity: 0; }
209}
210```
211 
212---
213 
214## PHP Requirements
215 
216- **Modern & Strict:** Target PHP 8.1+. Always start files with `declare(strict_types=1);`.
217- **Clean Code:** Adhere to a standard like PSR-12. Prefer composition over inheritance. Use exceptions for error handling.
218- **Leverage Modern Features:** Use constructor property promotion, `match` expressions, enums, and the nullsafe operator.
219 
220**Example: Modern PHP Class**
221 
222```php
223<?php
224declare(strict_types=1);
225 
226namespace App\Models;
227 
228use App\Db;
229use App\Enums\UserStatus;
230 
231readonly class User
232{
233 public function __construct(
234 private Db $db,
235 public int $id,
236 public string $name,
237 public UserStatus $status = UserStatus::Active,
238 ) {}
239 
240 public function getProfileUrl(): string
241 {
242 return '/users/' . $this->id;
243 }
244}
245```
246 
247---
248 
249## JavaScript Requirements (Progressive Enhancement Only)
250 
251- **Vanilla JS ONLY:** NO libraries or frameworks (including jQuery).
252- **Unobtrusive:** Assume JS might fail or be disabled. Core functionality must not depend on it.
253- **Modern & Safe:** Use ES2020+ features like `async/await`, optional chaining (`?.`), and `const`/`let`. Handle errors gracefully with `try/catch`.
254 
255**Example: Unobtrusive JS for a Toggle Button**
256 
257HTML (works without JS):
258 
259```html
260<a href="?show_details=true#details" class="toggle-link">Show Details</a>
261```
262 
263JavaScript (enhances the experience if it runs):
264 
265```javascript
266document.querySelector('.toggle-link')?.addEventListener('click', async (event) => {
267 event.preventDefault(); // Prevent default navigation
268 const details = document.querySelector('#details');
269 if (details) {
270 const isHidden = details.hidden;
271 // Use a View Transition for a smooth reveal if available
272 if (document.startViewTransition) {
273 document.startViewTransition(() => {
274 details.hidden = !isHidden;
275 event.target.textContent = isHidden ? 'Hide Details' : 'Show Details';
276 });
277 } else {
278 // Fallback for older browsers
279 details.hidden = !isHidden;
280 event.target.textContent = isHidden ? 'Hide Details' : 'Show Details';
281 }
282 }
283});
284```
285 
286---
287 
288## General Considerations
289 
290### 1. Database
291 
292Choose a database appropriate for the project's needs. SQLite is excellent for many sites due to its simplicity. For high-concurrency writes, consider MySQL or PostgreSQL. Regardless of the choice, always use **parameterized queries** to prevent SQL injection.
293 
294**Example: Secure Parameterized Query in PHP (PDO)**
295 
296```php
297<?php
298// Unsafe query (vulnerable to SQL injection)
299// $statement = $pdo->query("SELECT * FROM users WHERE id = " . $_GET['id']);
300 
301// Safe, parameterized query
302$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
303$stmt->execute(['id' => $_GET['id']]);
304$user = $stmt->fetch();
305```
306 
307### 2. Documentation
308 
309Consistent documentation is crucial. Follow established standards like PHPDoc for PHP and JSDoc for JavaScript to describe what a function does, its parameters, and what it returns:
310 
311**Example: Documenting a PHP Function (PHPDoc style)**
312 
313```php
314<?php
315/**
316 * Retrieves a user from the database by their ID.
317 *
318 * @param PDO $pdo The database connection object.
319 * @param int $userId The ID of the user to fetch.
320 * @return array|false The user data as an associative array, or false if not found.
321 * @throws InvalidArgumentException if the user ID is not a positive integer.
322 */
323function findUserById(PDO $pdo, int $userId): array|false
324{
325 if ($userId <= 0) {
326 throw new InvalidArgumentException('User ID must be a positive integer.');
327 }
328 $stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
329 $stmt->execute(['id' => $userId]);
330 return $stmt->fetch(PDO::FETCH_ASSOC);
331}
332```
333 
334### 3. Security
335 
336Security is a prerequisite, not a feature:
337 
338- **Sanitize Inputs, Escape Outputs:** Never trust user-provided data. Sanitize it on input and always escape it for the specific context of its output (e.g., HTML, SQL).
339- **CSRF Protection:** All state-changing requests (e.g., forms submitted via POST) must be protected against Cross-Site Request Forgery.
340- **Content Security Policy (CSP):** Implement a strict CSP to mitigate the risk of XSS and data injection attacks.
341 
342**Example: Basic CSRF Token Implementation**
343 
344```php
345<?php
346// In the script that displays the form:
347session_start();
348if (empty($_SESSION['csrf_token'])) {
349 $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
350}
351?>
352<form action="/submit" method="post">
353 <input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
354 <button type="submit">Submit</button>
355</form>
356 
357<?php
358// In the /submit script that processes the form:
359session_start();
360if (!isset($_POST['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
361 // Token is invalid or missing, reject the request.
362 http_response_code(403);
363 die('CSRF validation failed.');
364}
365// Proceed with processing the form...
366// Note: Do NOT unset the token here. Reusing the same token for the
367// user's session is more robust and prevents issues with multiple
368// tabs or the back button.
369?>
370```
371 
372**Example: Setting a Strict Content Security Policy Header in PHP**
373 
374```php
375<?php
376// This is a strict policy. It requires that all CSS and JavaScript
377// be loaded from external files hosted on the same domain.
378// No inline styles or scripts are allowed.
379$csp = "default-src 'self'; " .
380 "img-src 'self' https://images.example.com; " .
381 "style-src 'self'; " .
382 "script-src 'self'; " .
383 "form-action 'self'; " .
384 "frame-ancestors 'none'; " .
385 "object-src 'none'; " .
386 "base-uri 'self';";
387 
388header("Content-Security-Policy: " . $csp);
389?>
390```
391 
392---
393 
394## A Living Document
395 
396These guidelines are a starting point. The web platform evolves, and so should our practices. The core philosophy—simplicity, performance, and leveraging the native power of the web—remains constant. We champion this approach to build a better, faster, and more accessible web for everyone.
397 

Sections

  • AI Coding Agent Guidelines: The MPA-First Mandate
  • Introduction: Why We Build This Way
  • PRIME DIRECTIVE: MPA-Only Architecture
  • 🚫 BANNED TECHNOLOGIES & PATTERNS
  • Guiding Complex Changes
  • Folder Structure
  • SEO Best Practices: A Top Priority
  • 1. The Head is Everything
  • 2. Structured Data with JSON-LD
  • HTML Requirements
  • CSS Requirements
  • PHP Requirements
  • JavaScript Requirements (Progressive Enhancement Only)
  • General Considerations
  • 1. Database
  • 2. Documentation
  • 3. Security
  • A Living Document

What it covers

buildcode-stylearchitecturesecuritydatabaseuiagent-behaviourdocs

Glob targeting

  • **/*.php
  • **/*.html
  • **/*.js
  • **/*.css

Format

Cursor rules

The most expressive format here. Many small .mdc files, each with frontmatter declaring when it should load, so a rule about migrations only enters context when a migration is open. Costs the most to maintain and only one editor reads it.

What the corpus says about it

Repository

Owner
RealistSec
Language
—
License
—
Archived
no

All configs in this repo

Also in RealistSec/mpa-first-guidelines

Diff this repo’s formats

One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?

The other instruction files in this repository
RepositoryFormatStackCoversScoreChanged
RealistSec/mpa-first-guidelines.github/copilot-instructions.md · 10Copilot instructionsunclassifiedstyledependenciesuido-not+259/1003 days ago
RealistSec/mpa-first-guidelines.cursor/rules/mpa-relaxed-rules.mdc · 10Cursor rulesunclassifiedstylearchsecurityui+277/1003 days ago
Diff against .github/copilot-instructions.md Diff against .cursor/rules/mpa-relaxed-rules.mdc
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack