Skip to main content

Overview

ApiWebappManifest provides a MediaWiki API action (action=appmanifest) that generates a Web App Manifest for Progressive Web App (PWA) support. Namespace: MediaWiki\Skins\Citizen\Api Location: includes/Api/ApiWebappManifest.php Based on: MobileFrontend extension implementation Task: T282500 - This should eventually be merged to MediaWiki core

Constructor

The API module uses dependency injection for required services.
public function __construct(
    ApiMain $main,
    string $moduleName,
    Language $contentLanguage,
    HttpRequestFactory $httpRequestFactory,
    UrlUtils $urlUtils
)
main
ApiMain
required
Main API object
moduleName
string
required
Name of this API module (typically ‘appmanifest’)
contentLanguage
Language
required
Site content language
httpRequestFactory
HttpRequestFactory
required
Factory for making HTTP requests
urlUtils
UrlUtils
required
URL manipulation utilities

Configuration

The manifest is configured via $wgCitizenManifestOptions in LocalSettings.php:
$wgCitizenManifestOptions = [
    'short_name' => 'MyWiki',
    'description' => 'My awesome wiki',
    'theme_color' => '#131a21',
    'background_color' => '#fff',
    'icons' => [
        [
            'src' => '/path/to/icon-192.png',
            'sizes' => '192x192',
            'type' => 'image/png'
        ],
        [
            'src' => '/path/to/icon-512.png',
            'sizes' => '512x512',
            'type' => 'image/png',
            'purpose' => 'any maskable'
        ]
    ]
];
short_name
string
Short name for the app (shown on home screen)
description
string
Description of the wiki
theme_color
string
required
Theme color for browser UI (hex color)
background_color
string
required
Background color for splash screen (hex color)
icons
array
Array of icon objects. If empty, icons are auto-detected from $wgLogos

Methods

execute

Executes the API action and builds the manifest response.
public function execute(): void
Behavior:
  • Adds manifest fields to API result
  • Sets cache to 1 week (CACHE_MAX_AGE = 604800)
  • Sets cache mode to public
Manifest Fields Generated:
dir
string
Text direction (ltr or rtl) from content language
lang
string
Language code (e.g., en, de, ja)
name
string
Site name from $wgSitename
scope
string
Scope URL - set to server root (e.g., https://wiki.example.com/)
icons
array
Array of icon objects with src, sizes, type, and optionally purpose
display
string
Display mode - always standalone
orientation
string
Orientation preference - always natural
start_url
string
Start URL - main page URL from Title::newMainPage()->getLocalURL()
theme_color
string
Theme color from config
background_color
string
Background color from config
shortcuts
array
Array of shortcut objects linking to Special:Search, Special:Randompage, and Special:RecentChanges
short_name
string
Short name (only if configured)
description
string
Description (only if configured)

getIcons (private)

Gets icons from config or falls back to $wgLogos.
private function getIcons(): array
return
array
Array of icon objects with allowed keys: src, sizes, type, purpose
Icon Detection Logic:
  1. If $wgCitizenManifestOptions['icons'] is set, use those
  2. Otherwise, call getIconsFromLogos() to auto-detect from $wgLogos

getIconsFromLogos (private)

Auto-detects icons from $wgLogos configuration.
private function getIconsFromLogos(): array
return
array
Array of icon objects detected from logo files
Logo Keys Checked:
  • 1x - Standard resolution logo
  • 1.5x - 1.5x resolution logo
  • 2x - 2x resolution logo
  • icon - Icon logo
  • svg - SVG logo
Features:
  • Fetches logo files via HTTP to detect dimensions and MIME type
  • SVG logos get sizes="any" and type="image/svg+xml"
  • Skips logos where dimensions cannot be detected
Error Handling: Wrapped in try-catch - HTTP request failures are silently handled (empty content).

getShortcuts (private)

Generates PWA shortcuts for common special pages.
private function getShortcuts(): array
return
array
Array of shortcut objects with name and url keys
Default Shortcuts:
  • Search - Special:Search
  • Random page - Special:Randompage
  • Recent changes - Special:RecentChanges

getCustomPrinter

Returns custom JSON formatter for the manifest.
public function getCustomPrinter(): ApiWebappManifestFormatJson
return
ApiWebappManifestFormatJson
Custom printer that outputs proper JSON manifest format

API Usage

Endpoint

GET /api.php?action=appmanifest&format=json

Example Request

curl 'https://wiki.example.com/api.php?action=appmanifest&format=json'

Example Response

{
  "dir": "ltr",
  "lang": "en",
  "name": "My Wiki",
  "short_name": "MyWiki",
  "description": "An example wiki",
  "scope": "https://wiki.example.com/",
  "start_url": "https://wiki.example.com/wiki/Main_Page",
  "display": "standalone",
  "orientation": "natural",
  "theme_color": "#131a21",
  "background_color": "#ffffff",
  "icons": [
    {
      "src": "/resources/assets/icon-192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/resources/assets/icon-512.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any maskable"
    }
  ],
  "shortcuts": [
    {
      "name": "Search",
      "url": "https://wiki.example.com/wiki/Special:Search"
    },
    {
      "name": "Random page",
      "url": "https://wiki.example.com/wiki/Special:Randompage"
    },
    {
      "name": "Recent changes",
      "url": "https://wiki.example.com/wiki/Special:RecentChanges"
    }
  ]
}

Enabling the Manifest

The manifest is enabled via configuration:
// In LocalSettings.php
$wgCitizenEnableManifest = true;

// Optional: Customize manifest options
$wgCitizenManifestOptions = [
    'short_name' => 'Wiki',
    'theme_color' => '#11151d',
    'background_color' => '#ffffff'
];
When enabled, SkinCitizen::addMetadata() automatically adds:
<link rel="manifest" href="/api.php?action=appmanifest">

Caching

The API response is cached for 1 week (604,800 seconds) with public cache mode, making it suitable for CDN caching.

Security Considerations

The manifest is only linked when:
  1. $wgCitizenEnableManifest is true
  2. Anonymous users have read permission ($wgGroupPermissions['*']['read'] === true)
This prevents manifest exposure on private wikis.

Build docs developers (and LLMs) love