Wikipedia:User scripts/Guide: Difference between revisions

Content deleted Content added
Grammar, spelling, style, and link to JavaScript on Wikibooks, a sister Wikimedia project.
 
(19 intermediate revisions by 10 users not shown)
Line 28:
To make a [[Hello world]] program, insert the following code into your ''User:YourUserName/common.js'' file:
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">importScript('User:YourUserName/hello-world.js');</syntaxhighlight>
 
Next, create the page ''User:YourUserName/hello-world.js'', and insert this code:
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">$('#bodyContent').prepend('<p>Hello world!</p>');</syntaxhighlight>
 
This will write "Hello world!" on every page, below the title, until you remove the code. User scripts are written in [[JavaScript]], and both of the above code snippets are in JavaScript. The second snippet uses [[JQuery]], a JavaScript library that specializes in manipulating [[HTML]]. <code>$</code> is a JQuery [[Function (computer programming)|function]] that lets us target the [[HTML]] element we want. <code>#bodyContent</code> is a string in [[CSS selector]] syntax, and means target the HTML element with property <code>id="bodyContent"</code> . <code>prepend</code> is a JQuery function that inserts HTML code as a child of the <code>#bodyContent</code> element. <code><nowiki><p>Hello world!</p></nowiki></code> is the HTML code to be inserted.
 
=== Your first script ===
We will be writing ana independentuser modulescript by modifying your common.js, so you may want to get our [[Wikipedia:User scripts/Module template|module template]]. For the purpose of this tutorial, we will write a simple version of the [[Wikipedia:WikiProject User scripts/Scripts/Quick wikify|Quick wikify]] module, addingwhich adds the <code><nowiki>{{Wikify}}</nowiki></code> maintenance template to articlesthe top of an article when you click a link called "Wikify" in the "More" menu. To begin, change <code>MODULE_NAME</code> in the module template to "Qwikify". Your template should look like this:
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
// Qwikify
$( document ).ready( function () {
Line 46:
</syntaxhighlight>
 
In <code>MODULE_CODE</code>, we want to add the "Wikify" tab, so we will use the [[#Adding elements|<code>addPortletLink()</code> function]] (requiring the <code>mediawiki.util</code> module). Replace <code>MODULE_CODE</code> with a call to this function. Then we will bind an event handler so that when this link is clicked, we will call another function named <code>doQwikify()</code> that will actually execute the code. The <code>name</code> is what is shown on the tab, so set that to <code>'Wikify'</code>. Most tabs have an ID of <code>ca-''name''</code>, so set the ID to <code>'ca-wikify'</code>. The title (also known as [[mouseover]] or [[rollover]] text) should be something like <code>'Mark for wikification'</code>.

Lastly, we use jQuery's [//api.jquery.com/click/ .click()] to listen for clicks on this link, and when that happens, execute a function. After we call <code>doQwikify()</code>, it says <code>event.preventDefault()</code>. Since we clicked on a link, we need to tell the browser to prevent its default behavior (going to the URL, <code>'#'</code>). We want the page to stay right where it is at, so to prevent the browser from following the link, we prevent that and do our own custom action.
 
Altogether, your new function should look like this:
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
// Make sure the utilities module is loaded (will only load if not already)
mw.loader.using( 'mediawiki.util', function () {
// Wait for the page to be parsed
$( document ).ready( function () {
// See the "Portlets (menus and tabs)" subsection below
var link = mw.util.addPortletLink( 'p-cactions', '#', 'Wikify', 'ca-wikify', 'Mark for wikification');
$( link ).click( function ( event ) {
event.preventDefault();
Line 67 ⟶ 69:
Now, we must write our actual <code>doQwikify()</code> function. It will edit the edit box, so we need to get the name of that and its form. Viewing the source of the page shows that the form is named <code>editform</code> and the textbox is named <code>wpTextbox1</code>, meaning that the actual text is <code>document.editform.wpTextbox1.value</code>. To add {{tl|wikify}} (and two new lines), we simply do:
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
document.editform.wpTextbox1.value = "{" + "{wikify}}\n\n" + document.editform.wpTextbox1.value;
</syntaxhighlight>
Line 75 ⟶ 77:
Finally, we want to submit the form for the user. Luckily, JavaScript has a built-in function just for this named <code>submit()</code>. To submit our editing form, use <code>document.editform.submit()</code>. Your code should now look something like this:
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
function doQwikify() {
document.editform.wpTextbox1.value = "{" + "{wikify}}\n\n" + document.editform.wpTextbox1.value;
document.editform.submit();
}
</syntaxhighlight>
 
And that's it! Combine it all together and it should look like this:
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
// Make sure the utilities module is loaded (will only load if not already)
mw.loader.using( 'mediawiki.util', function () {
// Wait for the page to be parsed
$( document ).ready( function () {
// See the "Portlets (menus and tabs)" subsection below
var link = mw.util.addPortletLink( 'p-cactions', '#', 'Wikify', 'ca-wikify', 'Mark for wikification');
$( link ).click( function ( event ) {
event.preventDefault();
doQwikify();
} );
} );
} );
 
function doQwikify() {
document.editform.wpTextbox1.value = "{" + "{wikify}}\n\n" + document.editform.wpTextbox1.value;
Line 82 ⟶ 106:
</syntaxhighlight>
 
AndSave that'sthis it!to Save theyour ''User:YourUserName/common.js'' and then do a hard refreshpage. GoThen andgo editvisit a page such as the [[Wikipedia:Sandbox|Sandbox]], go into the "More" menu, click "Wikify", and seewatch whatthe happens!<ref>Thisuser sectionscript originallyadd writtenthe bymaintenance [[User:Raylu|raylu]]tag <sup>[[User:raylu/monobook.js|myfor monobookyou.js]]</sup>
Thanks a ton to all the users who helped improve this tutorial!</ref> Note that syntax highlighting must be disabled for this to work.
 
== Built-in scripts ==
Line 109 ⟶ 132:
The best and most recommended way to load a JavaScript file during development is from your local web server (see below for an easy way to install a web server). Put this string in your [[Special:Mypage/common.js|/common.js]]:
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
mw.loader.load( 'https://localhost/wikipediatest.js' );
</syntaxhighlight>
 
In some environmentenvironments, you need to write this likeas:<ref>https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content</ref>:
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
mw.loader.load( 'http://127.0.0.1/wikipediatest.js' );
</syntaxhighlight>
Line 143 ⟶ 166:
 
=== Text editors ===
You can use anything from a simple [[text editor]], to a more feature-packed [[code editor]] or [[Integrated development environment|IDE]]. Here are some featuresrecommended weeditors, recommend:by operating system.
 
* Color code JavaScript code
* Quickly insert standard JavaScript keywords and methods ([[code completion]])
** With the help of type definition libraries, you may also get code completion for the [[#Built-in scripts|globally available objects]] of [https://www.npmjs.com/package/types-mediawiki MediaWiki], [https://www.npmjs.com/package/@types/jquery jQuery], [https://www.npmjs.com/package/@types/oojs OOjs], and [https://www.npmjs.com/package/@types/oojs-ui OOUI].
* Show the list of all functions and quickly jump to any function
 
Here are some recommended editors, by operating system.
 
* Windows
Line 164 ⟶ 180:
** [[PhpStorm]] (not free, cross-platform, a free license for MediaWiki Developers is also available<ref>https://lists.wikimedia.org/pipermail/mediawiki-l/2010-June/034396.html</ref>)
* Linux
** [[Neovim]]/[[Emacs]]
** [[gedit]] (may come with Linux)
** [[Kate (text editor)|Kate]], (mayfor comeKDE-based with Linux)desktops
** [[GNOME Text Editor]], for [[GNOME]]
 
=== JavaScript Debuggers ===
Line 185 ⟶ 203:
One option is <code>[//api.jquery.com/ready/ .ready()]</code> from [[jQuery]].
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
// Define our main function
function myScript() {
Line 199 ⟶ 217:
 
Since the function is called only once, many users prefer to shorten this code with an [[anonymous function]]:
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
$( document ).ready( function () {
// ... code ...
Line 223 ⟶ 241:
Code that works with page content and avoids the aforementioned pitfalls may look like this:
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
mw.hook( 'wikipage.content' ).add( function ( $content ) {
const $target = $content.find( '.targetClass' );
Line 240 ⟶ 258:
</syntaxhighlight>
 
If your code works with page content and adds event handlers to DOM elements, then, instead of hooking to <code>'wikipage.content'</code> and looking for elements to attach event listeners to when it is fired, you may attach one event listener to an element outside of the content area or the whole <code>document</code> but filter events by a selector (see [https://api.jquery.com/on/#on-events-selector-data-handler jQuery's documentation]). That is, instead of writing <syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%" inline>$content.find( '.targetClass' ).on( 'click', ... )</syntaxhighlight> you can write <syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%" inline>$( document ).on( 'click', '.targetClass', ... )</syntaxhighlight>.
 
=== Finding elements ===
Every [[HTML]] element is a node in a [[Document Object Model|DOM]] model allowing scripts to access the element, for example, on the following HTML page.
 
<syntaxhighlight lang="html" copy style="min-width:fit-content; max-width: 40%">
<form name="frmname" id="frmid">
<textarea name="txtname" id="txtid"></textarea>
Line 253 ⟶ 271:
 
We can find element <code>textarea</code>:
* Using its <code>id</code>: <syntaxhighlight lang="js" copy style="min-width:fit-content; max-width: 40%" inline>$( '#txtid' )</syntaxhighlight>
* In the array of all elements with the same <code>tag</code>: <syntaxhighlight lang="js" copy style="min-width:fit-content; max-width: 40%" inline>$( 'textarea' )</syntaxhighlight>
* Using an element next to it: <syntaxhighlight lang="js" copy style="min-width:fit-content; max-width: 40%" inline>$( '#neighbor' ).prev()</syntaxhighlight>
* As a child of its parent: <syntaxhighlight lang="js" copy style="min-width:fit-content; max-width: 40%" inline>$( '#frmid' ).children( 'form' )</syntaxhighlight>
* As a form element, using <code>name</code>: <syntaxhighlight lang="js" copy style="min-width:fit-content; max-width: 40%" inline>$( '#frmid [name="txtname"]' )</syntaxhighlight>
 
'' [http://jsfiddle.net/compwhizii/j2QRf/ This example on jsFiddle] ''
 
The [//api.jquery.com jQuery API reference] is an excellent source for documentation.
Line 267 ⟶ 285:
Many scripts are supposed to work only on some pages. You can check:
 
* The page type<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
if ( mw.config.get( 'wgAction' ) === 'history' ) { // Continue only on history pages.
</syntaxhighlight>
* [[:mw:Manual:Interface/JavaScript#mw.config|<kbd>wg</kbd> (Wikimedia global) variables]]; many of them have the same meaning as [[Help:Magic words|Magic words]]<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
if ( mw.config.get( 'wgCanonicalNamespace' ) === 'User_talk') { // Continue only on User_talk pages.
</syntaxhighlight><syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
if ( mw.config.get( 'wgPageName' ) === 'Article_name' ) { // Continue only for the article "Article name".
</syntaxhighlight>
 
* Presence of elements (only in second and third parts of the script)<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
function func_start() {
if ( $( '#editForm' ).length == 0 ) return; //No edit form ? exit
Line 308 ⟶ 326:
 
==== Portlet structure ====
<syntaxhighlight lang="html" copy style="min-width:fit-content; max-width: 40%">
<div id="p-myname" class="portlet">
<h5>Header</h5>
Line 333 ⟶ 351:
* <code>nextNode</code> (optional) – element that this will be added in front of
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
// Several examples of portlet links
 
Line 352 ⟶ 370:
Or you can use JQuery. Simply attach it in another place with <code>.append()</code>, <code>.prepend()</code>, <code>.before()</code>, or <code>.after()</code>. [https://www.w3schools.com/jquery/jquery_dom_add.asp][https://javascript.info/article/modifying-document/before-prepend-append-after.svg]. Warning: This is fragile. You may get it working on a couple skins, but a couple other skins may look broken.
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
// Add a clickable button on the edit article page, above the edit summary.
$('.editOptions').prepend('<button type="button" id="my-custom-button">Do Things</button>');
Line 366 ⟶ 384:
To hide an element, you can use JQuery's [//api.jquery.com/hide/ <code>.hide()</code>] function.
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
// Example: remove special characters toolbar from edit page
$( '#editpage-specialchars' ).hide();
Line 385 ⟶ 403:
You can add menus using <code>mw.util.addPortlet()</code> (see [[wmdoc:mediawiki-core/master/js/module-mediawiki.util.html#.addPortlet|documentation]]). The menu will not show up until you put a portletLink in it. If you add a menu adjacent to #p-cactions, it will be a dropdown menu in the Vector and Vector 2022 skins, with the correct dropdown HTML added for you.
 
<syntaxhighlight lang="js" copy style="min-width:fit-content; max-width: 40%">mw.util.addPortlet('p-twinkle', 'TW', '#p-cactions');
mw.util.addPortletLink('p-twinkle', '#', 'Tag');
mw.util.addPortletLink('p-twinkle', '#', 'CSD');</syntaxhighlight>
Line 394 ⟶ 412:
The most important element on the edit page is a <kbd><textarea></kbd> with the article text inside. You can reference it with
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
var $textbox = $( '#wpTextbox1' );
</syntaxhighlight>
 
You can manipulate it using the [https://doc.wikimedia.org/mediawiki-core/master/js/jQueryPlugins.html#module-jquery.textSelection.html jquery.textSelection] ResourceLoader module.
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
var $textbox = $( '#wpTextbox1' );
$textbox.textSelection( 'setContents', 'This is bold!' );
Line 409 ⟶ 427:
Or you can grab <code><textbox></code>'s text, create a [[string (computer science)|string]], modify it, then write it back. Note; other editing tools might not recognise your changes or cause conflicts if you use this methodology instead of the textSelection api.
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
// Get value.
let value = $('#wpTextbox1').val();
Line 424 ⟶ 442:
==== Edittools ====
There is another edit panel under textarea. Usually it is generated from [[MediaWiki:Edittools]] by [[mw:Extension:CharInsert|Extension:CharInsert]] and consists of a lot of JavaScript links. In the English Wikipedia, this approach was replaced by [[MediaWiki:Gadget-charinsert.js]] and [[MediaWiki:Gadget-charinsert-core.js]].
 
==== Automatic and semi-automatic editing ====
You can automate the editing of a page using the following code template:
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width:40%;">
mw.loader.using("mediawiki.user", () => {
$.post( mw.config.get('wgScriptPath') + '/api.php', {
action: 'edit',
title: "[Page title]",
text: "[Text]",
summary: "[Edit summary]",
token: mw.user.tokens.get('csrfToken'), // This is the user token required to authorize the edit.
format: 'json'
}).then(function(r){
if (r.error) {
mw.notify(r.error.info, {type: 'error', title: 'Error while trying to edit'}); // Sends an error message if unable to edit the page.
}
});
});
</syntaxhighlight>
 
=== Doing something after another user script ===
Line 430 ⟶ 468:
One way to coordinate this is use the [https://doc.wikimedia.org/mediawiki-core/master/js/Hooks.html mw.hook] interface. Perhaps the other script sends a <code>[[#mw.hook('wikipage.content').add(...)|wikipage.content]]</code> event when it is done, or can be modified to do so (or you can ask the maintainer).
 
Another way to avoid this is to use a [https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver MutationObserver].
Another way to avoid this is to use the <code>DOMNodeInserted</code> or <code>DOMNodeRemoved</code> events to listen for when the other user script is finished, ensuring that your user script executes last.
 
<syntaxhighlight lang="javascript">$('body').on('DOMNodeInserted', '.preferences-link.link', function() {
// do things
}</syntaxhighlight>
 
=== User settings ===
Line 450 ⟶ 484:
You may want to place the following code at the top and bottom of your user script, in a comment. This will help prevent bugs, such as <code><nowiki>~~~~</nowiki></code> turning into your hard-coded signature when you save the page.
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">//<nowiki>
 
Your code here.
 
//</nowiki></syntaxhighlight>
 
If you need to print &lt;nowiki&gt; or &lt;/nowiki&gt; tags within your user script, use a trick such as <code>const tag = '</' + 'nowiki>';</code> to keep from messing up the nowiki tag on line 1 and on the last line.
 
=== Function scope ===
Line 460 ⟶ 496:
Do not declare named functions in the global namespace. For example, this is bad:
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">function submitEdit() {/* do stuff */}
 
$(function(){/* main code here */});</syntaxhighlight>
 
What if another of your user scripts also declares a <code><nowiki>submitEdit()</nowiki></code> function, but you have modified the code? This can lead to [[race conditions]] and hard-to-trace bugs. Instead, use classes named after your script, or place all your functions inside of an [[immediately invoked function expression]] (IIFE) such as <code><nowiki>$(function {});</nowiki></code>. JavaScript allows [[Nested function|nested functions]].
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">$(function(){
function submitEdit() {/* do stuff */}
Line 473 ⟶ 509:
 
== Ajax ==
[[Ajax (programming)|AJAX]] (''asynchronous JavaScript and XML'') is a popular name for a web programming technique that queries the server or fetches content without reloading the entire page. This is great for API requests. We do not have access to the SQL database in front end code, so the [[mw:Action_API|MediaWiki action API]] (or one of the [[mw:REST_API|other APIs]]) is the main way we retrieve data.
 
Although programming AJAX can be complex, libraries of functions can make it much easier. Since the [[mw:MediaWiki 1.16|1.16 release]], MediaWiki comes with the [[jQuery]] library, providing a convenient framework for easily making Ajax requests.
 
===Common problems===
* <p>AJAX programmers commonly run into problems if they do not account for AJAX's ''asynchronicity''. If you try to pop up a box with another page's content, you will almost certainly pop up a box containing <code>'''null'''</code>. This occurs because the script continued even though the query wasn't finished.</p><!--
 
--><p>To correct the problem, you need to use [[w:callback (computer science)|callback functions]]. Place the next portion of code after a query into a function, and call the function when the query completes. jQuery makes this easy to do.</p>
* AJAX scripts cannot reach a page on a different server (for example, ''google.ca'' or ''en.wikisource.org'' from ''en.wikipedia.org''). Trying to do so will cause the script to halt with or without error. This can be circumvented using a proxy on the current server, but none is available for Wikimedia user scripts.
 
=== Basic examples ===
==== mediawiki.api ====
MediaWiki provides some modules with helper functions facilitating the use of its API. The main modules available are
* [https://doc.wikimedia.org/mediawiki-core/master/js/mw.Api.html mediawiki.api]
Line 491 ⟶ 520:
 
Be sure to follow the [[meta:User-Agent policy|user agent policy]] by setting a user agent header (see code there). See also [[mw:API:Etiquette]].
 
==== Fetch page content ====
Fetching a page content can be done using [[GET (HTTP)|GET]].
<syntaxhighlight lang="javascript">
$.ajax({
url: mw.util.getUrl( 'Wikipedia:Sandbox' )
})
.then(function( data ) {
alert( 'The remote page contains:\n' + data );
})
.catch(function() {
alert( 'The ajax request failed.' );
});
</syntaxhighlight>
 
==== Get the wikitext of a page ====
 
===== Using module <code>mediawiki.api</code>=====
Note: make sure to add <code>mediawiki.api</code> to your dependencies!
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
function doSomethingWithText( wikitext ) {
/* .. */
Line 538 ⟶ 552:
</syntaxhighlight>
 
===== Using plain jQuery $.getJSON =====
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
$.getJSON(
mw.util.wikiScript('api'),
Line 565 ⟶ 579:
</syntaxhighlight>
 
====Edit= aUsing pagejQuery and$.ajax other common actions=====
Fetching a page content can be done using jQuery <code>$.ajax</code>, which does an HTTP [[GET (HTTP)|GET]] request.<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
$.ajax({
url: mw.util.getUrl( 'Wikipedia:Sandbox' )
})
.then(function( data ) {
alert( 'The remote page contains:\n' + data );
})
.catch(function() {
alert( 'The ajax request failed.' );
});
</syntaxhighlight>
 
==== Edit a page and other common actions ====
Scripts can perform common actions (like editing, protection, blocking, deletion, etc.) through the [{{SERVER}}/w/api.php API]. These actions require an edit token, valid for any action during the same session. (However, you should get a new token for different tasks in case this changes in the future.)
 
Line 571 ⟶ 598:
===== Using module <code>mediawiki.api</code>=====
Note: make sure to add <code>mediawiki.api</code> to your dependencies!
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
// Edit page via the mw.Api module.
// postWithEditToken( {} ) may be used instead of postWithToken("csrf", {} )
Line 602 ⟶ 629:
 
===== Using plain jQuery =====
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
// Edit page (must be done through POST)
// the line "text: info.text," will cause the call
Line 646 ⟶ 673:
Security warning: Do not load Wikipedia pages that do not end in .js into your script using this method, because anybody can edit those pages.
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">let title = "User:YourName/YourScript.js";
mw.loader.load( "https://en.wikipedia.org/w/index.php?title="+title+"&action=raw&ctype=text/javascript" );</syntaxhighlight>
 
Line 655 ⟶ 682:
Careful with <code>ctype</code>. Set it to <code>raw</code> for normal Wiki pages, and <code>application/json</code> for pages where a template editor or admin has set the [https://www.mediawiki.org/wiki/Help:ChangeContentModel Content Model] to JSON.
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">let jsonData;
let title = "User:YourName/YourData.json";
$.getJSON(mw.config.get('wgScriptPath')+'/index.php?action=raw&ctype=application/json&title='+title, function(data){
Line 663 ⟶ 690:
== Working with CSS ==
 
Some user scripts also use some CSS code, or even are built with CSS only. Then you need to code and test CSS code. That can be done invia your <kbd>[[Special:EditPage/Special:MyPage/common.css</kbd>,|editing butyour it is slow and''User:YourUserName/common.css'' messypage]].
 
=== Loading a localhost file ===
Instead, you can load a CSS file from your local web server (see the previous section for an easy-to-install web server). Put this line at the top of your [[Special:Mypage/common.css|/common.css]]:
For local development, you can load a CSS file from your local web server (see the previous section for an easy-to-install web server). Put this line at the top of your [[Special:Mypage/common.css|/common.css]]:
<syntaxhighlight lang="css">
<syntaxhighlight lang="css" style="min-width:fit-content; max-width: 40%">
@import "http://localhost/wikipediatest.css";
</syntaxhighlight>
'''Note!''' Such <code>@import</code> statements must come before any other declarations in your CSS., But there can be <code>/*except comments */</code> above them.
 
An alternative way is to put this line in your Javascript file[[Special:Mypage/common.js|/common.js]] instead:
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
mw.loader.load( 'http://localhost/wikipediatest.css', 'text/css' );
</syntaxhighlight>
Line 681 ⟶ 709:
Once you have finished the CSS code, you either need to paste it into your <kbd>/vector.css</kbd> if it is only for personal use. Or if it is for use by others then you should upload it to for instance [[Special:Mypage/yourscript.css|User:Yourname/yourscript.css]]. Then other users can import it by putting the following line in their <kbd>/common.js</kbd> file. Note, that is in their ".js", not their ".css".
 
<syntaxhighlight lang="javascript" copy style="min-width:fit-content; max-width: 40%">
importStylesheet( 'User:Yourname/yourscript.css' );
</syntaxhighlight>