All Broken Links

Last modified by Antoine Tran on 2021/03/18 11:28

cogProvides a UI to find all broken links in the wiki
Developed by


0 Votes
LicenseGNU Lesser General Public License 2.1


This code displays a list of checkboxes with the name of each space in your wiki. They are all checked by default, except for Panels, XWiki and Stats. You can uncheck other spaces which you don't want to search. When you press go, it finds all broken links residing in any page in the spaces checked.

These are the stats on my db running on Postgres on an Intel 2.66Ghz dual core. Links Examined: 592119 Total Pages in wiki: 401400 Time taken: 28.6 seconds

Will not find broken links located in Object content.

//allBrokenLinks 0.01
//By Caleb James DeLisle calebdelisle{{at}}lavabit_com
//queries database for all links which don't contain dollar signs or spaces (" ").
//removes links containing ' or multiple dots
//queries database for all document fullNames (even in non checked spaces), creates HashSet
//compares each link to HashSet, if no document found, link is reported.
int counter = 0;
ArrayList<String> spaces = xwiki.getSpaces();
String space;
   long startTime = new Date().getTime();
    ArrayList<String> lookInSpaces = request.getParameterMap().get("s");
    ArrayList<String> links = new ArrayList<String>();
    ArrayList<String> fullNames = new ArrayList<String>();
    String sql = "select lnk.fullName, from XWikiLink as lnk where not like '%\$%' and not like '% %' and "
    String out = "", fullName, link;

   if(lookInSpaces.size() > (spaces.size()/2)){
       while(counter < spaces.size()){
            space = spaces.get(counter);
                sql += "lnk.fullName not like '"+space+".%' and ";
        sql = sql.substring(0,sql.length()-5);
        sql += "(";
       while(counter < lookInSpaces.size()){
            sql += "lnk.fullName like '"+lookInSpaces.get(counter)+".%' or ";
        sql = sql.substring(0,sql.length()-4)+")";

    pairs =,0,0);
    ArrayList<String> pair;

    counter = pairs.size();
   while(counter > 0){
        pair = pairs.get(counter);
        link = pair.get(1);
       if(link.indexOf("'")==-1 && link.indexOf(".")==link.lastIndexOf(".")){
           //out += pairs.get(0)+" "+fullName+"\n";

    HashSet<String> docNames ="select doc.fullName from XWikiDocument as doc",0,0);

    counter = links.size();
   while(counter > 0){
            out += "; **"+links.get(counter)+"**\n: [["+fullNames.get(counter)+"]]\n\n";

    println("allBrokenLinks 0.01\nLinks Examined: "+links.size()+"\nTotal Pages in wiki: "+docNames.size()+"\nTime taken: "+(Math.round((new Date().getTime()-startTime)/100)/10)+" seconds\nThe following broken links were found:\n\n\n; **Broken Link**\n: Page Linked From\n\n"+out);
    println("{{html}}allBrokenLinks 0.01<br/>By Caleb James DeLisle<br/>Look for broken links on all pages in spaces:<form action=\"""\"><br/>");
   while(counter < spaces.size()){
        space = spaces.get(counter);
       if(space.equals("XWiki") || space.equals("Stats") || space.equals("Panels")){
            println("<input type=\"checkbox\" name=\"s\" value=\""+space+"\" />"+space+"<br/>");
            println("<input type=\"checkbox\" name=\"s\" value=\""+space+"\" checked=checked />"+space+"<br/>");
    println("<input type=submit value=\"Go!\"/></form>{{/html}}");

A much simpler and faster snippet, but which doesn't filter out false hits:

= Broken links =

#foreach ($l in $"select, link.fullName from XWikiLink link where not in (select distinct doc.fullName from XWikiDocument doc)"))
* [[$l.get(1)]] -> $l.get(0)

Prerequisites & Installation Instructions

To get it running, download the attachment, open it in a txt editor, copy the code, create a new wiki page, paste the code in, save as xwiki syntax 2.0 and view


Get Connected