Community Central
Community Central

This help page covers the more technical ways to include CSS and JavaScript on your community.

importArticles[]

The global JavaScript method importArticles() provides a common interface for including articles that contain scripts or styles on a community. It's most useful for importing scripts and styles conditionally.

The functionality is similar to the existing methods importScriptPage and importStylesheetPage. However, importArticles() can import articles from external communities, bundle several articles into one, minify them and serve them as a single request. This reduces both file size and web traffic, effectively making a community with a large number of additional files load a lot faster.

Usage[]

The importArticles() method relies on module definitions to load articles. Modules are essentially a JavaScript object with key/value properties. The following properties are used in most modules:

  • type (optional) - This property denotes the type of articles this module will contain. If omitted, the type will be guessed for each article based on its extension. The supported types are:
    • script - An article containing JavaScript (for example "MediaWiki:Common.js").
    • style - An article containing CSS (for example "MediaWiki:Common.css").
  • articles - The articles you wish to import. See the locating articles section below for more information on what to put here.

Any number of modules can be passed into importArticles().

Light bulb icon
Caching
Links generated by importArticles() (and the advanced techniques described below) are cached for a maximum of 10 minutes. So whenever you make a change you can assume that after 10 minutes all the users coming to your community will be served the updated version of JS and CSS files if importArticles() is used.

Locating articles[]

Simple syntax is used to locate the articles you're trying to import. It is very similar to, and compatible with, interwiki links:

(Prefix:<WikiName>:)<Article>

Anything in parentheses above is optional, and anything in brackets above denotes user input. The colon character is used to separate the string into different segments for parsing. Prefixes tell us how you want to look up the article and are generally followed by a community name, except in the case of a local community.

Articles must be in the MediaWiki namespace to load via importArticles or load.php. You cannot load articles from other namespaces, e.g. User. For this, instead use index.php with mw.loader.load or an appropriate legacy loading method.

Local articles[]

Articles on the local community can be located by title in the same way that you would link to them normally. They do not require a prefix or community name. For example, if you wanted to import the article MediaWiki:Common.js, the following would work inside an importArticles() statement:

MediaWiki:Common.js

External articles[]

Articles from external communities can also be located the same way that you would link to them normally. However, unlike local articles, external articles require the use of a prefix and community name to determine which community you will be importing them from and how you will identify that community. Fandom supports looking up communities by their URL. URL lookups are performed for the u prefix. For example, if you wanted to import the article Highlight.css from the Dev Wiki, the following would work inside an importArticles() statement:

u:dev:MediaWiki:Highlight.css

This syntax will also work for wikis in other languages. For example, if you wanted to import the article MediaWiki:Common.js from the Italian version of One Piece Wiki:

u:it.onepiece:MediaWiki:Common.js

Some wikis whose subdomain (the part before .fandom.com in their URL) contains a hyphen, or wikis that have moved from another subdomain in the past, won't always correctly resolve when using their current name. This results in a "missing" response from ResourceLoader. You can try removing the hyphen(s), using the old domain name, or using the wgDBName (mw.config.values.wgDBName in JavaScript). For example, genshin-impact uses genshinimpact. If you're still having trouble loading external articles this way, contact support.

Raw URLs must not be used with importArticles().

Advanced usage[]

Behind the scenes, the importArticles() method performs a number of necessary tasks:

  1. Encodes the article names with mw.util.wikiUrlencode.
  2. Enables test versions of scripts when test mode is enabled (by prepending the article name with test:).
  3. Registers the article as a module with ResourceLoader (assuming it is not already registered), which keeps track of its state and allows it to be used with mw.loader methods.
  4. Provides the user feedback in the case of an error.

It wraps mw.loader.using, which performs much of the actual work:

  1. Generates a properly formatted URL for use with ResourceLoader.
  2. Ensures that the module is not already loaded, or in the process of loading, before loading it.
  3. Performs sanity checks on the article names provided to assure they are properly formatted.
  4. Batches all imports together into a single request, and normalizes the request so that it can be more reliably cached.
  5. Creates a <script> element with the created URL, appending it to the document head, which initiates the load and script execution.
  6. Creates and returns a promise which is resolved on the "load" event of the created <script>.

Article registration[]

One of the most important roles of importArticles() is registering the article (i.e. a page on the wiki) as a module for use with ResourceLoader, so that it may be used with functions like mw.loader.using(). You may use mw.loader.using() directly, but not with articles before they have been registered as a module with importArticles(), or with mw.loader.register().

ImportJS, unlike importArticles, does not register articles as modules (only the ImportJS script itself, as ext.fandom.ImportJs). This means that a script present in both ImportJS and in calls to importArticles() will be downloaded and executed twice.

Depending on an imported article or module[]

importArticles returns a promise object that is resolved once all modules specified in the call have been loaded and executed, which may be used when you need to execute code that depends on the imported modules.

The promise is resolved with a single argument, a require function that, when passed the module name, returns the exported value of a module (typically an object may be used to control the module). Exported values are used so that scripts can expose functions and values to be used outside of the module, without littering the global scope. Despite this, most user scripts don't implement exports and instead opt to store methods in window.dev. Any functions that the module does not export or expose globally typically cannot be accessed.

importArticles({ type: "script", articles: "u:dev:MediaWiki:Script.js"})
.then(function(require){
    // Any code here is run after Script.js has been loaded and executed
    
    // Example of getting a module's exports
    var module = require("u:dev:MediaWiki:Script.js");
});

Following the first call to importArticles(), if you need to run code that depends on an imported article, you can call either importArticles() or mw.loader.using() with the module names as many times as you wish. If you have already called either of these methods with a particular module, or another imported script/module already depended on it, the module will not be re-downloaded or re-executed and the Promise will resolve either immediately (if the module has already been loaded and executed), or as soon as possible once this occurs.

Examples[]

Importing multiple script articles, one from the local community and one from an external:

importArticles({
    type: "script",
    articles: [
        "MediaWiki:MyCustomJavaScript.js",
        "u:dev:MediaWiki:External_include.js"
    ]
});

Importing multiple style articles, one from the local community and one from an external:

importArticles({
    type: "style",
    articles: [
        "MediaWiki:Common.css",
        "u:starwars:MediaWiki:External_include.css"
    ]
});

Importing multiple modules of different types in a single method call:

importArticles({
    type: "script",
    articles: [
        "MediaWiki:MyCustomJavaScript.js",
        "u:dev:MediaWiki:External_include.js"
    ]
}, {
    type: "style",
    article: "MediaWiki:Common.css"
});

Importing multiple modules in a single method call (in a single object, without the "type" property):

importArticles({
    articles: [
        "MediaWiki:MyCustomJavaScript.js",
        "MediaWiki:MyCustomStylesheet.css",
        "u:dev:MediaWiki:External_include.js",
        "u:dev:MediaWiki:External_include.css"
    ]
 });

The importArticles() method also supports a simplified, alternate syntax for common use cases. For convenience, the method importArticle() is also defined.

Including a single file from the local community using a module definition:

importArticle({
    type: "style",
    article: "MediaWiki:Common.css"
});

Importing CSS and JS manually[]

However, use of the importArticles() method is not strictly required to gain the benefits of combining and minifying multiple articles into one request. If you'd like, you can generate a URL manually, and load the assets using other means, such as @import statements in CSS or jQuery.getScript, mw.loader.load, or by manually injecting the script in JavaScript.

Using load.php[]

The load.php endpoint may be used to combine multiple articles into a single request, and is part of ResourceLoader. This is the preferred URL as it reduces bandwidth consumption by batching and minification, and the returned code automatically implements any articles passed as a module. importArticles() and mw.loader.using() (the client-side part of ResourceLoader) constructs requests using this endpoint.

While there are many parameters you can include in the URL, the following are probably the most useful:

Parameter Parameter Description
mode Tells ResourceLoader that we will be loading articles. If the mode is "articles", only articles will be loaded.
articles The list of articles (pages) or modules to fetch. If multiple articles are provided, they should be separated by a pipe "|" character. The syntax described above may be used here. The mode must be "articles" when specifying articles.
modules

The list of modules or articles (pages) to fetch. If multiple modules are provided, they should be separated by a pipe "|" character. A comma "," can be used to repeat modules within the same "endpoint" as the previous module in the list. For example "ext.fandom.foo,bar" will request the modules "ext.fandom.foo" and "ext.fandom.bar". The mode parameter may be omitted when specifying modules. The syntax described above may be used here.

A full list of modules is available at runtime via mw.loader.moduleRegistry and mw.loader.getModuleNames(). Core modules included with MediaWiki are listed here.

In addition:

  • ext.fandom.site and user are site scripts (being Common.js and Fandomdesktop.js) and user scripts (being User:<name>/common.js and User:<name>/Fandomdesktop.js) respectively.
  • Likewise site.styles and user.styles are the site styles (Common.css and Fandomdesktop.css) and user styles.
  • The module ext.fandom.ImportJs returns the scripts present in MediaWiki:ImportJS.

only The type of articles to import. Should be set to either "scripts" or "styles", or may be omitted if fetching a mix of both. When only is specified, the script/style is returned without being wrapped in a mw.loader.implement() call, and will therefore not be registered as a module.

If you want your article to be implemented and registered as a module rather than run directly, only should not be specified. The module will be registered using the exact name provided in articles or modules

debug This parameter is not necessary by default but can be set to one of three values to allow for easier debugging of problems within the imported articles:
  • 2 (modern mode): Disables minification and batching of the returned scripts, loads each module's debugScripts, disables caching both server-side and client-side.
  • 1 or true (legacy mode): Same as the above, but the script is implemented directly which may produce more meaninful stack traces.
  • 0 or false or omitted: Disables debugging (this also overrides the resourceLoaderDebug cookie if it is set.)

See the associated documentation here.

lang Used to request the article/module from a specific language on this wiki. By default, requests from mw.loader.using() always request the English version of a module.
skin Used to requests site scripts/styles for a specific skin, overriding the skin that the logged-in user has set. Only used if either the site or user module is being requested.
user Used to request user scripts/styles for a specific user, overriding the currently logged-in user. Only used if the user module is being requested.
version

The version hash is a checksum of the content of the module. It isn't necessarily used to request a specific software version of a script, instead it is used as part of the cache control system. For most cases, it shouldn't be used directly.

When a version is set in the URL, the script is cached on the server so that the next request (using that version) will be served significantly faster. The server only caches the module if it is considered "worthy" (has more than 360 unique cache misses on the server in an hour), where versioned modules are cached for 30 days and unversioned for 5 minutes. On the client side, subsequent requests of that version will use the browser's local cache and the edge cache (CDN) for up to 1 minute, after which it must be fetched from the server. Requests without a version will be cached for 5 minutes on the client and on the edge cache, however in this case the returned response will contain a request which points at the latest version.

Multiple modules use a combined version hash, a "hash of hashes" in order to invalidate the batched cache if any of the modules contained within are changed.

Furthermore, core modules are cached in localStorage at the key MediaWikiModuleStore:<wgDBname> (where <wgDBname> is the database name of your wiki). When loading a module via mw.loader, localStorage will be checked for a cached module before a request is made.

In the end, you should end up with a URL that looks something like this. This is a relative URL, and refers to resources kept locally on the wiki:

/load.php?mode=articles&articles=MediaWiki:One.css|MediaWiki:Two.css&only=styles

If the resource is hosted on another Fandom community, you can use an absolute URL, including the domain name and protocol:

https://dev.fandom.com/load.php?mode=articles&articles=MediaWiki:One.css|MediaWiki:Two.css&only=styles

...or alternatively use the u: syntax described above:

/load.php?mode=articles&articles=u:dev:MediaWiki:One.css|u:dev:MediaWiki:Two.css&only=styles

If the resource is hosted or websites outside of Fandom such as Dropbox, you should use the full url, like this asset file for example.

https://dl.dropboxusercontent.com/s/0p9ay0nqibx2wr7/manga_list.css

Using index.php[]

The index.php endpoint may be used to request a single unaltered, non-linted, non-minified script or stylesheet. This may be useful for debugging, or if you need to bypass ResourceLoader for some reason (i.e. implementing ES6 user scripts).

index.php cannot be used to fetch modules specifically, only pages. Additionally interwiki links and u syntax is not supported when action=raw is specified, so an absolute URL is needed to get scripts/stylesheets from other communities. For JavaScript, using external third party sites may open up a security risk and should only be imported from a site inside Fandom.

While there are many parameters you can include in the URL, the following are probably the most useful:

Parameter Parameter Description
title The title of the page to load.
curid The ID of the wiki page to load. May be used as a more permanent identifier of the page, as it won't change if the page is moved to another name. The title is ignored if this is present.
action Must be set to "raw" to get the raw content of the page.
ctype The content-type value to be returned in the HTTP header of the response from the server. Required when importing a script, as your browser will typically reject scripts without an executable MIME type. Must be text/javascript for JS and text/css for CSS.

In the end, you should end up with a URL that looks something like this:

/index.php?action=raw&title=MediaWiki:Script.js&ctype=text/javascript

Implementing[]

Once you have your URL, it may be used with the following methods:

mw.loader.load(modules, type)
If type is "text/javascript" or unspecified, creates a <script> element with a src attribute of the URL specified in the first argument, then appends it to the document head.

If type is "text/css", creates a <link> element with a ref attribute of "stylesheet" and a href attribute of the URL specified in the first argument, then appends it to the document head.

If module names are specified instead of URLs (when the string isn't prefixed with "http://" or "/"), this function acts like mw.loader.using().

The argument modules cannot be an array when using URLs. You should batch multiple modules in the same request using load.php, or have a separate call for each URL when using index.php.

When specifying only in the load.php URL, calling this function multiple times with the same module URL will cause it to be executed again on each call, as the module won't be self-registering and aware that it has already been loaded.

@import
See @import method.
Manual injection
If you don't want to rely on any libraries, you can inject the script yourself with the following code:
var script = document.createElement("script");
script.src = url;
script.addEventListener("load", function() {
    // Any code here is executed when the script has loaded
});
document.head.append(script);
And for a stylesheet:
var link = document.createElement("link");
link.rel = "stylesheet";
link.href = url;
link.addEventListener("load", function() {
    // Any code here is executed when the stylesheet has loaded
});
document.head.append(link);

Legacy loading methods[]

The following legacy methods are provided automatically in the global scope.

importScript(title)
Constructs a relative URL with a title, then calls mw.loader.load with it, which appends a <script> element to the document head:
<script src="/index.php?title=title&action=raw&ctype=text/javascript"></script>
importScriptURI(url)
Calls mw.loader.load, passing it a url, which appends a <script> element to the document head, as follows.
<script src="url"></script>
importScriptPage(title, wiki)
Constructs an absolute URL to a script on a Fandom wiki given a title, then calls mw.loader.load with it, which appends a <script> element to the document head, as follows. If wiki is null, this is the same as importScript.
<script src="http://wiki.fandom.com/index.php?title=title&action=raw&ctype=text/javascript"></script>
importStylesheet(title)
Constructs a relative URL to a local stylesheet with a title, then creates and appends a <link> element to the document head, as follows.
<link rel="stylesheet" type="text/css" href="/index.php?title=title&action=raw&ctype=text/css">
importStylesheetURI(url, media)
Constructs a <link> element with a url, and appends it to the document head, as follows.
<link rel="stylesheet" type="text/css" href="url" media="media">
importStylesheetPage(title, wiki)
Constructs an absolute URL to a stylesheet on a Fandom wiki given a title, then creates and appends a <link> element to the document head, as follows. If wiki is null, this is the same as importStylesheet.
<link rel="stylesheet" type="text/css" href="http://wiki.fandom.com/index.php?title=title&action=raw&ctype=text/css">
appendCSS(css)
Constructs a <style> element containing your css rules directly, and appends it to the document head.
<style type="text/css">css</style>

See also[]

Further help and feedback[]