CtrlK
BlogDocsLog inGet started
Tessl Logo

adobe/aem-edge-delivery-services

Skills for building AEM Edge Delivery Services sites — block development, content modeling, code review, testing, and page import.

82

1.04x
Quality

76%

Does it follow best practices?

Impact

88%

1.04x

Average score across 6 eval scenarios

SecuritybySnyk

Advisory

Suggest reviewing before use

Overview
Quality
Evals
Security
Files

review-checklist.mdskills/code-review/resources/

PR Review Checklist

Detailed checklist for reviewing Edge Delivery Services pull requests. Use this as a reference when reviewing PRs.

PR Structure Checklist

Required Elements

ItemDescriptionPriority
Preview URL (Before)URL showing current state on main branchBLOCKING
Preview URL (After)URL showing changes on feature branchBLOCKING
PR DescriptionClear explanation of what and whyBLOCKING
Scope AlignmentChanges match title/descriptionHIGH
Issue ReferenceLink to GitHub issue (for bug fixes)RECOMMENDED
Test PlanHow changes were testedRECOMMENDED

Preview URL Format

Before: https://main--{repo}--{owner}.aem.page/{path-to-test-content}
After: https://{branch}--{repo}--{owner}.aem.page/{path-to-test-content}

PR Description Template

## Description
[What changed and why]

## Related Issue
Fix #<issue-number>

## Test URLs
- Before: https://main--{repo}--{owner}.aem.page/{path}
- After: https://{branch}--{repo}--{owner}.aem.page/{path}

## Types of Changes
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Styling change
- [ ] Refactor

## Checklist
- [ ] Linting passes
- [ ] Tested across viewports
- [ ] No console errors
- [ ] Performance validated

JavaScript Checklist

Linting & Style

CheckSeverityNotes
ESLint passesBLOCKINGairbnb-base config
No eslint-disable without justificationHIGHSpecific disables with comments OK
No global eslint-disableBLOCKINGNever acceptable
ES6+ featuresMEDIUMUse modern syntax
Import extensionsMEDIUMInclude .js extensions

Architecture

CheckSeverityNotes
No frameworks in critical pathHIGHAffects LCP/TBT
Libraries via loadScript()HIGHNot in head.html
Consider IntersectionObserverMEDIUMFor heavy libraries
aem.js unmodifiedBLOCKINGSubmit upstream PRs
No new build stepsHIGHWithout team consensus

Code Patterns

CheckSeverityNotes
Re-use existing DOMMEDIUMDon't recreate elements
Scoped selectorsHIGHBlock-specific
No hardcoded configMEDIUMExternalize values
No debug console logsHIGHClean up before merge
Proper error handlingMEDIUMWhere appropriate
No CSS in JSHIGHUse CSS classes

Anti-Patterns to Flag

// ANTI-PATTERN: Inline styles
element.style.color = 'red';
element.style.display = 'none';

// PREFERRED: CSS classes
element.classList.add('error');
element.classList.add('hidden');

// ANTI-PATTERN: innerHTML with styles
el.innerHTML = '<style>.foo { color: red; }</style>';

// PREFERRED: External CSS
// Add styles to block's CSS file

// ANTI-PATTERN: Hardcoded values
const API_URL = 'https://api.example.com';
const TIMEOUT = 5000;

// PREFERRED: Configuration
import { API_URL, TIMEOUT } from './config.js';

// ANTI-PATTERN: Global disable
/* eslint-disable */
function doSomething() { }

// PREFERRED: Specific disable with reason
/* eslint-disable-next-line no-param-reassign -- DOM element modification */
element.disabled = true;

CSS Checklist

Linting & Style

CheckSeverityNotes
Stylelint passesBLOCKINGStandard config
No !important without justificationHIGHPrefer specificity
Property order preservedMEDIUMDon't reorder in functional PRs

Scoping & Selectors

CheckSeverityNotes
Block-scoped selectorsBLOCKING.block-name .selector
Prefixed private classesMEDIUMblock-name-private
Simple, readable selectorsMEDIUMAdd classes vs complex selectors
ARIA attributes for statesLOW[aria-expanded="true"]

Responsive Design

CheckSeverityNotes
Mobile-first approachHIGHBase = mobile, media queries for larger
Standard breakpointsHIGH600px, 900px, 1200px
min-width onlyMEDIUMDon't mix with max-width
All viewports testedHIGHMobile, tablet, desktop

Frameworks & Preprocessors

CheckSeverityNotes
No Sass/Less/PostCSSHIGHWithout team consensus
No Tailwind/etcHIGHWithout team consensus
Native CSS featuresMEDIUMEvergreen browser support

Anti-Patterns to Flag

/* ANTI-PATTERN: Unscoped selector */
.title {
  font-size: 2rem;
}

/* PREFERRED: Block-scoped */
main .hero .title {
  font-size: 2rem;
}

/* ANTI-PATTERN: !important overuse */
.button {
  background: blue !important;
  color: white !important;
}

/* PREFERRED: Higher specificity */
main .hero .button {
  background: blue;
  color: white;
}

/* ANTI-PATTERN: Mixed breakpoint directions */
@media (max-width: 599px) {
  .block { padding: 1rem; }
}
@media (min-width: 900px) {
  .block { padding: 2rem; }
}

/* PREFERRED: Consistent mobile-first */
.block {
  padding: 1rem; /* mobile */
}
@media (min-width: 600px) {
  .block { padding: 1.5rem; }
}
@media (min-width: 900px) {
  .block { padding: 2rem; }
}

/* ANTI-PATTERN: Complex, unreadable selectors */
.block > div:first-child > ul > li:nth-child(2) > a {
  color: red;
}

/* PREFERRED: Add semantic classes */
.block .nav-link-secondary {
  color: red;
}

Performance Checklist

CheckSeverityNotes
Lighthouse mobile greenBLOCKINGIdeally 100
Lighthouse desktop greenBLOCKINGIdeally 100
No libs in head.htmlBLOCKINGCritical path
No layout shiftsHIGHCLS impact
Images optimizedHIGHSize and format
IntersectionObserver for heavy opsMEDIUMDefer loading
No sync blocking operationsHIGHRender blocking
Reasonable bundle sizeMEDIUMNo unnecessary minification

Performance Testing

# Check preview URLs with PSI
# Mobile
https://pagespeed.web.dev/analysis?url=https://{branch}--{repo}--{owner}.aem.page/{path}&form_factor=mobile

# Desktop
https://pagespeed.web.dev/analysis?url=https://{branch}--{repo}--{owner}.aem.page/{path}&form_factor=desktop

Content & Authoring Checklist

CheckSeverityNotes
Author-friendly structureMEDIUMEasy to understand
Backward compatibilityHIGHExisting content works
No breaking migrationsHIGHContent shouldn't need updates
No hardcoded stringsMEDIUMUse placeholders/spreadsheets
No committed binariesHIGHUnless code-referenced

Security Checklist

CheckSeverityNotes
No secrets committedBLOCKINGAPI keys, passwords, etc
No XSS vulnerabilitiesBLOCKINGSanitize user input
No innerHTML with user dataBLOCKINGUse textContent
CSP headers (tools)HIGHFor tool pages
External links safeMEDIUMrel="noopener noreferrer"
No eval() or Function()BLOCKINGCode injection risk

Security Patterns

// ANTI-PATTERN: XSS vulnerability
element.innerHTML = userInput;

// PREFERRED: Safe text content
element.textContent = userInput;

// ANTI-PATTERN: Unsafe URL construction
const url = `https://api.example.com?q=${userInput}`;

// PREFERRED: URL encoding
const url = `https://api.example.com?q=${encodeURIComponent(userInput)}`;

// ANTI-PATTERN: Missing rel attribute
<a href="https://external.com" target="_blank">Link</a>

// PREFERRED: Secure external links
<a href="https://external.com" target="_blank" rel="noopener noreferrer">Link</a>

Visual Validation Checklist

Screenshot Capture

CheckSeverityNotes
Desktop screenshot capturedHIGH1200px viewport
Mobile screenshot capturedHIGH375px viewport
Tablet screenshot capturedMEDIUM768px viewport
Block-specific screenshotMEDIUMIf block changes
Before/After comparisonMEDIUMFor visual changes

Visual Assessment

CheckSeverityNotes
Layout correct across viewportsHIGHNo broken layouts
No visual regressionsHIGHCompare to main branch
Colors consistentMEDIUMWith design system
Typography correctMEDIUMFont sizes, weights
Images display properlyHIGHSize, aspect ratio
Icons visibleHIGHAll icons render
Dark mode worksMEDIUMIf applicable
Animations smoothLOWIf applicable

Common Visual Issues

IssueWhat to Look For
Layout breaksElements overlapping, overflowing, misaligned
Text issuesTruncation, overflow, wrong font, poor contrast
Image problemsWrong size, aspect ratio, missing, broken
Responsive failuresLayout not adapting to viewport
Spacing issuesInconsistent margins, padding
Color problemsWrong colors, poor contrast, dark mode issues
Icon issuesMissing, wrong size, wrong color

Screenshot Commands

# Using the capture-screenshots.js utility
cd .claude/skills/pr-review/scripts
npm install
node capture-screenshots.js <after-url> [before-url] [output-dir] [block-selector]

# Examples
node capture-screenshots.js https://branch--repo--owner.aem.page/path
node capture-screenshots.js https://branch--repo--owner.aem.page/path https://main--repo--owner.aem.page/path
node capture-screenshots.js https://branch--repo--owner.aem.page/path "" ./screenshots ".hero"

Embedding Screenshots in PR Comment

## Visual Preview

### Desktop (1200px)
![Desktop Screenshot](path/to/desktop.png)

### Mobile (375px)
![Mobile Screenshot](path/to/mobile.png)

<details>
<summary>Additional Screenshots</summary>

### Tablet (768px)
![Tablet Screenshot](path/to/tablet.png)

### Block Detail
![Block Screenshot](path/to/block.png)

</details>

Accessibility Checklist

CheckSeverityNotes
Semantic HTMLHIGHProper element usage
Heading hierarchyHIGHSequential, no skips
Alt text for imagesHIGHDescriptive
ARIA labelsMEDIUMFor interactive elements
Keyboard navigationHIGHTab order, focus states
Color contrastHIGHWCAG AA compliance
Focus visibleMEDIUMClear focus indicators

Review Severity Guide

BLOCKING (Must Fix)

  • PR cannot be merged until resolved
  • Examples: security issues, linting failures, missing preview URLs, breaking changes

HIGH (Should Fix)

  • Should be resolved before merge
  • Examples: performance issues, accessibility violations, code quality concerns

MEDIUM (Recommended)

  • Strong recommendation to fix
  • Examples: best practice violations, maintainability concerns

LOW (Consider)

  • Nice-to-have improvements
  • Examples: code style preferences, documentation enhancements

tile.json