Primo – Useful bookmarklets

For those of us who are not developers, the IGeLU Primo Working Group has compiled a list of various tools for Primo to help our community, as created by customers or provided by Ex Libris

Any queries can be addressed to the Coordinator at

Bookmarklet areas


Benefits of bookmarklets

  • You can activate useful tools with one click on a bookmarklet, with the outcome of actions such as adding text to the end of the URL quickly and easily
  • For example, avoiding adding this text to the end of the URL repeatedly: &showPnx=true

How to create a simple bookmarklet

  • Base: javascript:document.location=document.location+’CHANGE THIS BIT
  • Example: javascript:document.location=document.location+’&showPnx=true’

How to add a bookmarklet to your browser

  • Right click on Bookmark toolbar
  • Choose Add page (Chrome) or New bookmark (Firefox)
  • Add a suitable short but indicative entry into the Name field, such as PNX
  • Paste the javascript into the Location field
  • Click Save (Chrome) or Add (Firefox)

Bookmarklets List

Customization Package

Display customisation code issues with AngularJS, Ex Libris, May 2022 Release (This was for a limited time for upgrade to AngularJS 1.8 in the November 2022 Release, but keeping for historical info)

Custom JS for Primo BO, Gabriele Höfler

  • Show your local custom javascript for Primo Back Office sites aka on primo-explore. Refreshes the same browser tab
    • javascript:location.href=location.href.replace(/primo-explore.vid=((.+?)(&|$))./,’primo-explore/custom/$2/

Custom JS for Primo VE, Nir Zinger

  • Show your local custom javascript for Primo VE sites aka on discovery. Refreshes the same browser tab
    • javascript:location.href=location.href.replace((/discovery.*vid=((.+?)(&|$)).*/),’discovery/custom/$2/js/custom.js’).replace(/:([^:]*)$/, ‘-‘ + ‘$1’);

No Customisation, Ex Libris

  • Removes your local custom code to see Primo OTB UI, useful to quickly see if local code is causing a
    conflict, or if it’s an Ex Libris OTB issue. Refreshes same browser tab
    • javascript:document.location=document.location+’&noCustomization=true’

Show Directives, Gabriele Höfler

  • If looking at a list of brief results, this bookmarklet will display the text for web writing. Refreshes the
    same browser tab
    • javascript:(function(){var script=document.createElement(“SCRIPT”);script.src=’…entsByTagName(“head”)[0].appendChild(script);var checkReady=function(callback){if(window.jQuery){callback(jQuery)}else{window.setTimeout(function(){checkReady(callback)},100)}};checkReady(function($){$(‘primo-explore’).find(‘[parent-ctrl=”$ctrl”]’).each(function(){$(this).append(‘/g,”).replace(/-([a-z])/g,function(m,w){return w.toUpperCase()})+'” style=”display:block;height:auto;color:black;”>Hover for id’)})})})();

Record Data

Primo New UI Bookmarklet, developed by Gabriele Höfler

  • Latest version is March 2020, available here:
  • Displays the following in Brief Results and Full Record Display
    • Record ID
      • Record Types: Local and External CDI
      • Search States: Main Primo Basic Search and Advanced Search, additional search states of Browse Search, Journal Search, Database Search, and Newspaper Search, and externally on Primo Services Page
      • Action: n/a as display only
      • Also shows Preferred/generic FRBR record text for Local records, where the resource is in a FRBR group (n/a for CDI as logical match and merge record rather than FRBR)
      • nb Primo Services Page Record ID starts with RS, instead of the usual TN_ for CDI records
    • Show PNX
      • Record Types: Local and External CDI
      • Search States: Main Primo Basic Search and Advanced Search, additional search states of Browse Search, Journal Search, Database Search, and Newspaper Search, and externally on Primo Services Page
      • Action: Opens new browser tab
      • Primo Services Page via Google Scholar and databases like Scopus will only appear when there is no full text if direct linking is enabled
      • Primo Services Page shows the OpenURL data and technically not true PNX, as the record does not exist in the Primo database but is created dynamically from the source citation data
      • FRBR: Show PNX shows preferred record and Show Source Record shows all source records for the preferred record, with line separation
      • Dedup: Show PNX shows dedupmrg record and Show Source Record shows all source records, with line separation
      • Note for VE: Primo VE does not have a true PNX, with a fundamentally different publishing model from Alma with Primo Back Office, but it does have similar data available as a json representation
    • Show Source Record
      • Record Types: Local records only, as CDI records do not have a stored source record available to customers
      • Search States: Main Primo Basic Search and Advanced Search, additional search states of Browse Search and Database Search
      • Action: Opens new browser tab
      • Displays original data, such as MARC for Alma & Dublin Core for OAI
      • Note: This is the Source Record in the Primo Database at the time of last harvest / update, which is then normalized into PNX. It is not necessarily an exact replica of the source record at the data source right now, which is yet to be harvested
      • Not available: Primo VE NZ consortia records and instead display a message that the Record ID xxxx is not in the database. These sites could use the workaround to ‘Display Source Record’, although this does display also to users
    • Show RIS
      • Record Types: Local records only
      • Action: Opens new browser tab
      • Uses Classic UI call, as not yet available for New UI (same data, just different URL)
      • Not available: External CDI records, and not available for Primo VE local records as per using a Classic UI call , and VE was only ever on New UI
    • Known Issues
      • Show PNX on the Services page redirects to a Redirect URL (the one from Classic UI to New UI)
      • Show Source Record for Journal Search redirects to main Primo with general error message
      • No outcome of clicking on bookmarklet when used in the full record overlay, experienced with the August 2021 Release, occurring if results are set to 50 results per page AND if not yet scrolled all the way to the bottom of the page, to incrementally load all results

Show PNX, Ex Libris

  • If looking at the full record, this bookmarklet will display the PNX for the record in the same browser tab
    • javascript:document.location=document.location+’&showPnx=true’

Show XML and PNX, Mehmet Celik

  • If looking at brief results, displays links for both the PNX and the original local XML record
    • javascript:(() => {Array.from(document.querySelectorAll(‘prm-brief-result-container’)).forEach((el) => { let controller = angular.element(el).controller(el.localName); let recordid = controller.item.pnx.control.recordid[0] || null; if (recordid) { let div = document.createElement(‘div’);’flex’;’row’; =’space-around’; div.innerHTML = <a target=”_blank” href=”/primo_library/libweb/jqp/record/${recordid}.xml?needSession=0″>xml</a> <a target=”_blank” href=”/primo_library/libweb/jqp/record/${recordid}.pnx?needSession=0″>pnx</a>; el.append(div); }});})()

See Source ID , Jim Robinson

  • If looking at brief results, add a static non-clickable source record ID to every record, for quick results review
  • javascript:(function(){var%20h1s=document.querySelectorAll(‘.item-title’);for(let%20h1%20of%20h1s){var%20a=h1.children[0].href;a.replace(/[?&]+([^=&]+)=([^&]*)/gi,function(m,k,v){if(k==’docid’){var%20cd=document.getElementById(‘SEARCH_RESULT_RECORDID_’+v);var%20pd=cd.parentNode;pd.insertBefore(document.createElement(‘div’).appendChild(document.createTextNode(v)),cd);}});}})()

See raw OAI data, Stacey van Groll

  • When looking at a source system record in its UI and seeking to see the raw OAI data, use the bookmarklet and then if desired, use Ctrl-U to reveal the source code. Example
    • javascript:(function(){“/view/”, “/v2/oai?verb=GetRecord&metadataPrefix=oai_dc&”),”OAI-PMH”)})();

Search Queries and Results

DBID search switch, Bill Constantine

  • Run a quick keyword search by the DBID of a CDI collection in Primo, and then use the bookmarklet to change the query and rerun results on the dbid field, to find all CDI results for that DBID by query=dbid,contains,xxx
    • javascript:(function(){DBIDcode= location.href.split(“?”)[1].split(“&”)[0].split(“,”)[2];qregex=/(query=.+,.+,.+?)(&|$)/;location.href=location.href.replace(qregex,%27query=dbid,contains,%27+DBIDcode+%27$2%27);})();

DBID query prompt, Stacie Traill

  • When in Primo, use the bookmarklet to trigger a popup with a text box. Add the DBID of a CDI collection to the free text field, and click Ok to initiate the search, returning results by: query=dbid,contains,xxx
    • javascript:(function(){dbcode = window.prompt(“DBID: “); qregex = /(query=.+,.+,.+?)(&|$)/;%20location.href=location.href.replace(qregex,%27query=dbid,contains,%27+dbcode+%27$2%27);%20})();

Changing your View by prompt for Primo BO, Stacey van Groll

  • Presents a popup box to type in your VID to easily change between views
    • javascript:location.href=location.href.replace(/explore.*/,’explore/search?vid=’+prompt(‘VID?’,’Your View

Display results from a specific ‘page’, Stacey van Groll

  • Change the offset parameter in the URL to display results for a specific ‘page’, such as changing the offset from &offset=0 to &offset=11, or 101, or 501, or 1001, etc
    • javascript:location.href=location.href.replace(/&offset*/,’&offset=’+prompt(‘offset?’,’add offset here’));

CDI Activation Analysis Tool, Ex Libris

  • If looking at a list of brief results, this tool will add a ‘CDI Activation Analysis’ link, leading to an Ex Libris interface to run a check on your institutional holdings. The query will return details of the reason why the result is in your Primo results, including by CDI collections active for search and/or full text
  • Find the bookmarklet and instructions here:
  • Tip! You can also examine your Institutional Holdings File to help troubleshoot CDI problems. See details on how to get access to this here: Publishing to Central Discovery Index

Email a page, Deborah Fitchett (

  • Opens your mail client with the URL in the body and page title as the subject line
    • javascript:(function(){location.href=’’+location.href+’&subject=’+document.title;})();

From MARC to OCLC, Deborah Fitchett (

  • Prompts for a MARC field and goes to a URL based on that. Builds in “if”s and “else”s to deal with OCLC’s complicated URL naming schemes so it can cope with holdings and LDR fields. Opens in a new window
    • Simple: javascript:(function(){var field=prompt(‘MARC field?’);if(field){location.href=’’+field.charAt(0)+’xx/’+field+’.html’;}})();
    • Complex: javascript:(function(){s=prompt(“MARC%20field?”);if(s){”,’_blank’,’menubar=yes,scrollbars=yes,location=no,height=600,width=850′);if(s==”ldr”||s==”LDR”){pwin.location=””;}else{f=s.charAt(0);if(s>840&&s<880){d=”holdingsformat”;}else{d=”bibformats”;}pwin.location=””+d+”/en/”+f+”xx/”+s+”.html”;}}})();

From Primo via DOI, Deborah Fitchett (

  • Goes to a URL based on the DOI selected on the page
    • javascript:(function(){var%20s=document.selection?document.selection.createRange().text:window.getSelection?window.getSelection().toString():document.getSelection?document.getSelection():”;if(s){location.href=’’+s;}else{alert(‘You%20need%20to%20select%20a%20DOI%20first.’);}})();

New window to learn more, Deborah Fitchett (

  • Opens a new window with a URL based on text selected. Example for Maori dictionary to look up more details of a term in a record
    • javascript:(function(){var%20s=document.selection?document.selection.createRange().text:window.getSelection?window.getSelection().toString():document.getSelection?document.getSelection():”;if(s){”,’_blank’,’scrollbars=yes,height=600,width=800′);w.location=’’+s;}})();

Copy Record ID, Browser URL, & Send To Citation to clipboard, and include template text, Valerie Florez

  • UPDATE: This bookmarklet now also converts the citation to sentence case, such as if the title is in all capitals
  • Workflow: Open full record display (overlay or full page) > use the bookmarklet (Note: This triggers the Citation menu to activate – wait for the Citation to generate in the Send To menu) > data is held in clipboard and can be pasted into an email, notepad etc
    • javascript:(function(){if(!document.querySelector(“#CitationButtonFullView”)){alert(“Citation button not found”);}else{document.querySelector(“#CitationButtonFullView”).click();}new Promise(resolve=>{if(typeof document.getElementsByClassName(“csl-entry”)[0]!==”undefined”){return resolve(document.getElementsByClassName(“csl-entry”)[0]);}const observer=new MutationObserver(()=>{if(typeof document.getElementsByClassName(“csl-entry”)[0]!==”undefined”){var str=document.getElementsByClassName(“csl-entry”)[0].textContent.replace(/([^\W_]+[^\s-]*) */g,function(txt){return txt.charAt(0).toUpperCase()+txt.substr(1).toLowerCase();});var lowers=[‘A’,’An’,’The’,’And’,’But’,’Or’,’For’,’Nor’,’As’,’At’,’By’,’For’,’From’,’In’,’Into’,’Near’,’Of’,’On’,’Onto’,’To’,’With’,’Https’,’Www’,’Http’];var pnxId=String(document.location.href.toLowerCase().split(‘docid=’)[1].split(‘&’)[0]);for(i=0,j=lowers.length;i<j;i++)str=str.replace(new RegExp(‘\\b’+lowers[i]+’\\b’,’g’),lowers[i].toLowerCase());str=str.replace(/([:\?]\s+)(.)/g,function(txt){return txt.toUpperCase();});var forEL=String(pnxId)+String(“\r\n\r\nURL of the search results view:\r\n”)+String(document.location.href)+String(“\r\n\r\nCitation from search results view:\r\n”)+String(str)+String(“\r\n\r\nScreenshot of error: \r\n\r\nThanks\,\r\nYour Name”);var output=document.createElement(“textarea”);output.textContent=forEL;document.body.appendChild(output);;try{document.execCommand(“copy”);}catch(err){navigator.clipboard.writeText(forEL);}document.body.removeChild(output);resolve(document.getElementsByClassName(“csl-entry”)[0]); observer.disconnect();}});observer.observe(document.body,{subtree:true,childList:true});});})();
  • Example text:
    • cdi_proquest_journals_2163339241
    • URL of the search results view:
    • xxxxx
    • Citation from search results view:
    • Oyedokun, T. T., Oyewumi, F. a., Akanbi, M. L., & Laaro, D. M. (2018). Assessment of Ict Competencies of Library Staff in Selected Universities in Kwara State, Nigeria. Library Philosophy and Practice, I–.
    • Screenshot of error:
    • Thanks,
    • Your Name


Show Performance, Ex Libris

  • See loading times in milliseconds and assess performance. Adds block to top of screen after refreshing same browser tab. Close browser tab to remove
  • Note: Seemed to not be working for Server monitor section for Primo VE in very late 2019, but working as of early 2020, just with different data
    • javascript:document.location=document.location+’&show_performance=true’
  • Details / example
    • Client monitor
      • total search time: 876
      • search api response time: 651
      • results render time: 225
    • Server monitor
      • total search api time: 34
      • search time: 14 — the time Primo takes to search the index and get the records
      • delivery manager time: 116 — time to calculate the availability of different records. This calculation was separated from the search api process in 2017 to improve performance

System Management

Material Type position editing on Primo BO, Gabriele Höfler

  • Quickly move entries many positions up or down in Primo BO Views Advanced Search Tiles Configuration
  • Change the up to down as needed and the resource type as needed
  • Example for moving Newsletter Articles up
    • javascript:(function() {document.getElementById(‘Newsletter Articles-up’).click()})();

Display field position editing on Primo BO, Gabriele Höfler

  • Quickly move full record display field entries many positions up or down in Primo BO Views Full Display Full Results Tiles Configuration
  • Change the up to down as needed and the field type as needed
  • Example for moving Contents up
    • javascript:(function() { var labelTextSearchedFor = ‘Contents’; var labels = document.getElementsByTagName(‘label’); var alertMissing = true; for (var i = 0; i < labels.length; i++) { var label_id = labels[i].id; var label_text = labels[i].textContent; if (label_text == labelTextSearchedFor && label_id) { var field_number = label_id.match(/^fieldDesc-(\d+)-\d/); var alertMissing = false; setActionAndSubmit(‘up ‘+field_number[1]); return false; } label_id = null; label_text = null; } if (alertMissing) { alert(‘Could not find Element with label ‘ + labelTextSearchedFor); }})();

Display label codes, Tamara Marnell

  • When hovering over an element in Primo UI, see a tooltip with the underlying label code, allowing for quick identification of the code to change in the controlling source system eg Alma or Primo BO
    • javascript:(function() {const labels = document.querySelectorAll(‘[translate]’);for (let i=0; i<labels.length; i++) {let label = labels[i];label.setAttribute(‘title’, label.getAttribute(‘translate’));};})();

Edit content temporarily, Deborah Fitchett (

  • Makes the content of the current page temporarily editable
    • javascript:(function(){document.body.contentEditable=’true’;document.designMode=’on’;void(0);})();

Use an external stylesheet temporarily, Deborah Fitchett (

  • Applies a stylesheet from the location of your choice to the current page
    • javascript:(function(){var%20style=document.createElement(‘link’);style.rel=’stylesheet’;style.type=’text/css’;style.href=’’;document.getElementsByTagName(‘head’)[0].appendChild(style);})();

Run a script, Deborah Fitchett (

  • Runs a javascript file from the location of your choice on the current page
    • javascript:(function(){var%20script=document.createElement(‘script’);’YourScriptID’;script.src=’’;document.body.appendChild(script);})();

Access Issues

Add proxy to URL, Stacey van Groll (but lots of people have a version!)

  • When testing access issues, check if proxy is involved by adding your standard prepend. Example
    • javascript:void(location.href=’’+location.href)

Context Object

Display CTO on Primo BO, Stacey van Groll

  • Right click on the View It or Get It frame and then select View frame source
    • javascript:location.href=location.href.replace(‘openurl?’,’openurl?svc_dat=CTO&debug=true&’)

Display CTO on Primo VE, Ex Libris

  • Displays In the full record display, after refreshing the page
    • javascript:document.location=document.location+’&displayCTO=true’
  • Note: To see the Target URL field also, you must copy the Incoming URL, and add this to the end:
    • &debug=true&svc_dat=CTO

UResolver Debug View, Jeff Peterson

Notes on CTO – what is it and why should you care?

  • CTO stands for Context Object and it is a hugely valuable troubleshooting tool!
  • CTO display gives a view into the metadata of a record (and beyond if augmentation such as CrossRef is enabled), which is being used by the Link Resolver to match to bibliographic records and return associated services as a result of those matches
  • The display includes valuable information such as
    • the target URL and the standards identifiers
    • record numbers from Alma to do further checking and correlate to activation collections, such as your 61 ID for electronic collections and your 51 ID for your portfolios
    • a full list of services resulting from the bibliographic match, parser parameters, and resolution URL
    • and any filters showing why a particular service might be hidden from users, such as Date Filter True due to coverage not matching the record