Extension:PWA

From mediawiki.org
MediaWiki extensions manual
PWA
Release status: beta
Implementation Skin
Description Transforms a wiki into a PWA
Author(s) Antoine Mercier-Linteau (Tinsstalk)
Latest version 0.3b (2022-10-18)
MediaWiki 1.31+
License GNU General Public License 2.0
Download

The PWA extension transforms any MediaWiki installation into a PWA (Progressive Web Application). Subsets of the wiki can be configured to run under different PWA configurations.

Progressive web applications allows a wiki to run in a standalone browser page on Android or iOS (or any OS for that matter) and integrate with the environment as if it were a full-fledged app rather than a browser tab.

Compared to native mobile apps, PWAs have the following advantages:

  • harness the full power of the web
  • fully reuse you mobile skin or responsive design as well as all of you wiki's functions and extensions (code once, deploy everywhere), allowing your wiki to be truly multi platform without the heavy development and maintenance costs of having dedicated web, android and iOS apps
  • allow you to entirely bypass the App Store or Google Play
  • update themselves just like any website rather than having to publish versions.

PWAs can access most of their platform's hardware (cameras, speakers, microphones, GPS) and can even work offline and show push notifications.

They are very reliable on most platforms except iOS as Apple is really lagging behind in term of feature implementation. This is best explained by the technology allowing developers to completely bypass the 30% publication fee they levy on the App Store and their whole vetoing process of apps.

Their main caveat is that their install logic differs from a native app. Basically speaking, users need to add them to their home screen to install them. On Android, this involves tapping a simple prompt. On iOS, the user needs to manually add a shortcut to their homescreen in Safari.

Live demo[edit]

For a live demo, head to https://wikimedi.ca (preferably on a mobile phone) and scroll to the bottom of the page to find the install buttons.

Installation[edit]

  • Download and place the file(s) in a directory called PWA in your extensions/ folder.
  • Add the following code at the bottom of your LocalSettings.php file:
    wfLoadExtension( 'PWA' );
    
  • Yes Done – Navigate to Special:Version on your wiki to verify that the extension is successfully installed.

Deploying your PWA[edit]

The PWA extension does not work out of the box, it requires a few steps to inform browsers on how to best present your app to the world.

Browsers are informed of the existence of a PWA through the <link rel="manifest" href="/manifest.json" /> tag in ‎<head>. The extension takes care of outputting that tag with the correct link.

For detailed information on how PWAs work behind the scene, see this page.

Step 0: requirements[edit]

Your MediaWiki installation needs to be served over HTTPS, else the PWA installation process will simply not work.

The MobileFrontend extension is strongly recommended and so is a mobile skin (such as Minerva or a responsive skin).

Step 1: configure LocalSettings.php[edit]

See the #Configuration section for detailed explanations of each settings.

Configuring a single PWA[edit]

This PWA will be available on each page of your wiki.

	
wfLoadExtension( 'PWA' );
$wgPWAConfigs =	[
	"main" => [
		"manifest" => "MediaWiki:manifest.json",
		"patterns" => ["/.*/"] // Match all pages.
	]
];

Configuring multiple PWAs[edit]

	
wfLoadExtension( 'PWA' );
$wgPWAConfigs =	[
	"help" => [
		"manifest" => "MediaWiki:help-manifest.json",
		"patterns" => ["/Help:.*/"] // Match all pages in the Help namespace.
        // The start_url and scope parameters of the manifest will indicate which URL is to be handled by this PWA.
	],
	"main" => [
		"manifest" => "MediaWiki:main-manifest.json",
		"patterns" => ["/.*/"] // Match all pages.
	]
];

The extension iterates over all PWA extensions in order and selects the first match for inclusion in the rendered page. Whenever an install button is clicked on that page, it's the currently available PWA that will be installed and none other.

Configuring a development PWA[edit]

Having a production and development version of your PWA is useful when you're experimenting with your manifest.json file or making changes to a service worker.

	
wfLoadExtension( 'PWA' );
$wgPWAConfigs =	[
	"main-dev" => [
		"manifest" => "MediaWiki:main-dev-manifest.json",
		"patterns" => ["/Project:PWA*/"] // Only display the development PWA on that page.
	],
	"main" => [
		"manifest" => "MediaWiki:main-manifest.json",
		"patterns" => ["/.*/"] // Match all pages.
	]
];

Step 2: create your manifest.json[edit]

Manifests tell the browser how your web content should be displayed by the OS. Where a manifest parameter is configured in LocalSettings.php you must create a json file in your wiki. This is the simplest of manifest:

				
{
  "name": "My PWA"
}

See this page on web.dev for a full list of the parameters. You can also check this wiki's main PWA manifest.

Your manifest can be debugged using DevTools in Chromium-based browsers or the Inspector tool in Firefox.

Some of the manifest's parameters will have side effects on the wiki:

  • start_url: if different from the general main page (MediaWiki:mainpage), all links to the main page will be replaced with it's value (so that PWA apps can have their own main page).

Step 2.1: make sure all URLs have the pwa-id parameter[edit]

This extension uses the pwa-id=pwa-id_as_defined_in_LocalSettings.php URL parameter to know which PWA is currently making requests. Failure to add that parameter will still yield a working PWA, but features sur as edit tags or custom home pages will fail to work.

Here is an example of a PWA with custom home and shortcuts:

				
{
  "name": "My PWA",
  "start_url": "/wiki/Home?pwa-id=main",
  "shortcuts": [
     {
        "short_name": "Notifications",
        "name": "Notifications",
        "url": "/wiki/Special:Notifications?pwa-id=main"
     },
     {
        "short_name": "Watchlist",
        "name": "Watchlist",
        "url": "/wiki/Special:Watchlist?pwa-id=main"
     }
  ]
}

Step 3: define a ServiceWorker[edit]

In order to be installable, a ServiceWorker must accompany your PWA. Define it in MediaWiki:PWA-your_PWA's_name-serviceWorker.js.

				
self.addEventListener("install", event => {
   console.log("Service worker installed");
});
self.addEventListener("activate", event => {
   console.log("Service worker activated");
});
self.addEventListener("fetch", event => {
   console.log("Service worker fetch");
});

Step 4: make some icons[edit]

At the very least, PWAs need one 512 by 512 pixels icon and one 192 by 192 pixels icon. One corresponding apple-touch-icon link tag will be set for each image/png MIME type icon defined in the manifest. apple-touch-icon link tags defined by other extensions will be overridden.

All icons are set in your manifest page.

Step 5: define your recent changes tags[edit]

To track which edit was made with the PWA in standalone mode and to (gather trafic stats), the extension defines a general recent changes tag named PWA-standalone-edit. It also defines one tag per PWA with the following syntax PWA-standalone-edit-PWAName.

Labels and descriptions for those tags need to be defined in Special:Tags.

Step 6: have visitors install your PWA[edit]

For now, you have access to two install buttons:

  • {{#PWAAndroidInstall:id}}
  • {{#PWAiOSInstall:id}}

Where id is the id you used in LocalSettings.php to define each PWA. If you define install buttons for many PWAs, only those for the current PWA will work. Others will be disabled.

Depending on which button they click, the following will happen:

  • On Android and other browsers (including desktop Safari), the browser will prompt the user with a native dialog if they want to install the PWA and will do so upon request.
  • On iOS, a gif animation instructing the user on how to manually add the PWA to the home screen is shown (iOS chooses not to implement the prompt logic [because PWAs drive customers and developers away from the App Store]).

This step requires images for the button in the language of the wiki. The package provides then in English (android-install-en.svg and iOS-install-en.svg) and French (android-install-fr.svg and iOS-install-fr.svg). For other languages the button images have to be added to the directory .../extensions/PWA/resources/ext.PWA/, e.g. by simply copying the English files. For example, for German the images android-install-de.svg and iOS-install-de.svg are required.

Customizing your PWAs further[edit]

The extension provide several facilities to customize your PWAs further:

  • MediaWiki:PWA-common.css: CSS that is included only from within your PWAs
  • MediaWiki:PWA-mobile.js: JS that is included only from within your PWAs
  • Service workers code (coming soon): code that will be run from withing your service worker.

Configuration[edit]

Variable Default Description
$wgPWAConfigs
				
{
	"default": {
		"manifest": "default-manifest.json",
		"patterns": ["/.*/"],
	}
}
Configurations for the PWAs available in this MediaWiki installation. Array keys are unique IDs for each PWA.
  • manifest is the system message (in the MediaWiki namespace) holding the manifest.json data
  • patterns is an array of PHP regexes that match page patterns and link to that manifest file.
$wgPWAMobileSkin Minerva The name of the skin used for the mobile version. Set to false if there is none.

Adding install buttons to skins[edit]

Here is an example on how you might add install buttons to various skins.

After you have initialized the extension in LocalSettings.php, add:

$wgHooks['SkinAddFooterLinks'][] = function ( Skin $skin, string $key, array &$footerlinks ) 
{
    global $wgParser;
	
	if ( $key === 'places' ) 
	{
		if($skin->skinname == 'minerva') // Using the mobile skin.
		{
			// Hide in standalone mode.
			$style = '<style>#footer-places-appbuttons { float: right; display: inline-block; } #footer-places-appbuttons::after { display:none; } @media all and (display-mode: standalone) { #footer-places-appbuttons { display: none; } }</style>';
		}
		else // Using the default skin.
		{
			// Hide in standalone mode.
			$style = '<style>#footer-places-appbuttons { position: absolute; margin-top: 3em; } @media all and (display-mode: standalone) { #footer-places-appbuttons { display: none; } }</style>';
		}

		$footerlinks['appbuttons'] = $style.MediaWiki\Extension\PWA\PWA::PWAiOSInstall($wgParser, 'main', 35)[0].'&nbsp;'.MediaWiki\Extension\PWA\PWA::PWAAndroidInstall($wgParser, 'main', 35)[0];;
    };
};

Integration on the App Store or Google Play[edit]

The main caveat of PWAs is that their install logic differs from a native app. PWAs need to be added to the home screen using the browser rather than installed from the App Store or Google Play. Google allows PWAs on Play as Trusted Web Activities (TWA) but with Apple products it's another story.

There have been reports of developers being able to package PWAs and push them on the App Store. However, most apps will likely fail to pass Apple's app requirements.

See also[edit]