# Blog Pagination Guide

**Last Updated:** 2026-01-09

## Overview

This guide documents the blog pagination system implementation, including URL patterns, page number logic, SEO optimization, accessibility features, and best practices.

## URL Patterns

### Index Pages

- **Page 1**: `/insights/` (no `/page/1/`)
- **Page 2+**: `/insights/page/2/`, `/insights/page/3/`, etc.

### Category Pages

- **Page 1**: `/insights/{category}/` (no `/page/1/`)
- **Page 2+**: `/insights/{category}/page/2/`, `/insights/{category}/page/3/`, etc.

**Valid categories**: `lexikon`, `ratgeber`, `inside-ordio`

## Page Number Display Logic

### Desktop (max 7 pages)

The pagination component shows up to 7 page numbers around the current page:

- **Near start**: Shows pages 1-7, then ellipsis, then last page
- **Middle range**: Shows page 1, ellipsis, 5 pages around current, ellipsis, last page
- **Near end**: Shows page 1, ellipsis, then last 7 pages

### Mobile (max 5 pages)

On mobile devices, the component shows up to 5 page numbers to save space.

### Examples

- **Page 1/10**: `1, 2, 3, 4, 5, 6, 7, ..., 10`
- **Page 5/10**: `1, ..., 2, 3, 4, 5, 6, 7, 8, ..., 10`
- **Page 10/10**: `1, ..., 4, 5, 6, 7, 8, 9, 10`

## SEO Optimization

### Meta Tags

All paginated pages include:

- **Canonical URL**: Points to the current page URL
- **rel="prev"**: Link to previous page (if not on page 1)
- **rel="next"**: Link to next page (if not on last page)

Example:

```html
<link rel="canonical" href="https://www.ordio.com/insights/page/2/" />
<link rel="prev" href="https://www.ordio.com/insights/" />
<link rel="next" href="https://www.ordio.com/insights/page/3/" />
```

### Schema Markup

Paginated pages use `CollectionPage` schema with pagination properties:

```json
{
  "@type": "CollectionPage",
  "url": "https://www.ordio.com/insights/page/2/",
  "pagination": {
    "@type": "Pagination",
    "currentPage": 2,
    "totalPages": 9
  }
}
```

## Accessibility Features

### ARIA Labels

- **Navigation**: `aria-label="Seitennavigation"` on `<nav>` element
- **Current page**: `aria-current="page"` on current page number
- **Disabled buttons**: `aria-disabled="true"` on prev/next when disabled
- **Page links**: Descriptive `aria-label` on each page number link
- **Ellipsis**: `aria-hidden="true"` to hide from screen readers

### Keyboard Navigation

- **Arrow keys**: Navigate between pagination links
- **Home/End**: Jump to first/last page
- **Enter/Space**: Activate focused link
- **Tab**: Standard tab order through links

### Screen Reader Support

- **Live region**: Announces current page and total pages
- **Status updates**: Updates when navigating between pages
- **Semantic HTML**: Proper use of `<nav>`, `<a>`, and `<span>` elements

## Mobile Optimization

### Touch Targets

- **Minimum size**: 44x44px (WCAG 2.1 AA compliant)
- **Spacing**: Adequate spacing between elements
- **Text size**: Readable font size (0.875rem minimum)

### Responsive Behavior

- **Fewer page numbers**: Shows max 5 pages on mobile vs 7 on desktop
- **Flexible layout**: Wraps to multiple lines if needed
- **Touch-friendly**: Larger padding and margins for easier tapping

## URL Validation

### Edge Cases Handled

- **Page 0**: Redirects to page 1 (301)
- **Negative pages**: Redirects to page 1 (301)
- **Pages beyond total**: Redirects to page 1 (301)
- **Non-numeric pages**: Redirects to page 1 (301)
- **Invalid categories**: Returns 404

### Validation Logic

1. Parse page number from URL
2. Validate it's numeric and >= 1
3. Check it's <= total_pages
4. Redirect if invalid, otherwise proceed

## Implementation Files

### Components

- **Pagination Component**: `v2/components/blog/Pagination.php`
- **JavaScript**: `v2/js/blog-pagination.js`
- **CSS**: `v2/css/blog.css` (lines 1628-1750)

### Templates

- **Index Page**: `v2/pages/blog/index.php`
- **Category Page**: `v2/pages/blog/category.php`

### Configuration

- **Meta Generator**: `v2/config/blog-meta-generator.php`
- **Schema Generator**: `v2/config/blog-schema-generator.php`

## Usage

### Basic Usage

```php
// Set pagination variables
$current_page = 1; // Current page number (1-based)
$total_pages = 9; // Total number of pages
$posts_per_page = 12; // Posts per page
$base_url = '/insights/'; // Base URL for pagination
$show_page_numbers = true; // Show page numbers

// Include pagination component
include __DIR__ . '/../../components/blog/Pagination.php';
```

### With Category

```php
$base_url = '/insights/lexikon/';
include __DIR__ . '/../../components/blog/Pagination.php';
```

## Testing

### Audit Script

Run the pagination audit script to test all functionality:

```bash
python3 scripts/blog/audit-pagination.py
```

The script tests:

- URL pattern generation
- Page number calculations
- SEO meta tags
- Accessibility attributes
- Edge case handling

### Manual Testing

1. **Test all page numbers**: Navigate through all pages
2. **Test edge cases**: Try invalid page numbers, page 0, etc.
3. **Test mobile**: Check responsive behavior on mobile devices
4. **Test keyboard**: Navigate using keyboard only
5. **Test screen reader**: Use screen reader to verify announcements

## Troubleshooting

### Pagination Not Showing

- Check that `$total_pages > 1`
- Verify `$show_page_numbers` is `true`
- Check that pagination component is included

### Wrong Page Numbers

- Verify `$current_page` and `$total_pages` are correct
- Check that posts are loaded correctly
- Ensure `$posts_per_page` matches actual posts displayed

### SEO Issues

- Verify canonical URLs are correct
- Check that rel="prev" and rel="next" are present
- Validate schema markup with Google Rich Results Test

### Accessibility Issues

- Test with keyboard navigation
- Verify ARIA labels are present
- Check screen reader announcements

## Best Practices

1. **Always validate page numbers** before displaying
2. **Use semantic HTML** for better accessibility
3. **Include SEO meta tags** for all paginated pages
4. **Test on mobile devices** to ensure responsive behavior
5. **Provide clear navigation** with prev/next buttons
6. **Handle edge cases gracefully** with redirects
7. **Maintain consistent URL structure** across all pages

## Related Documentation

- [Blog Template Development Guide](TEMPLATE_DEVELOPMENT_GUIDE.md)
- [Blog Component API](COMPONENT_API.md)
- [Blog Frontend Patterns](FRONTEND_PATTERNS_EXTRACTION.md)
