fetching bibliography to web page: current best practice


I'd like to fetch a filtered set of citations (usually a collection) from zotero and display them on a web page, preferably with the citeproc formatting handled either by the server or through some very simple specification of a style. Is there a current best practice that uses one or more javascript libraries that can easily be used in a web page (that is, not in a node application)?

I see for instance the Zotero publications github repo, but it seems somewhat complicated, less flexible than I would hope, and npm install fails won my machine... I'm hoping there's something more actively maintained that other people are already using!

  • Really depends on a lot of things. There are a number of options here:
    including both ready-made plugins such as ZotPress and libraries for python and php.

    I don't think there's an easy to implement javascript library, so if you want this client side, you'll likely have to build it yourself.
  • Thanks so much @adamsmith. Doesn't look like there's an obvious choice for client-side js, so I'll start playing with the API and see what I get. If I am able to produce something useful (won't happen right away) I;ll post back here!
  • OK, already have a quick question: while it seems pretty straightforward to get a fomatted bibliography (at least for less than 150 items) with "times/top/?format=bib" I guess it is longstanding practice not to wrap url's in links/a tags via CSL. Does this suggest that I should get the raw data form Zotero, munge the URL myself, and send to a CSL processor that I set up myself?

    If there's a way to avoid that step, then this turns out to be a very trivial task indeed (though I guess I'd have to figure out pagination on my own, and also I guess "limit" is not accepted when format=bib, so that's its own issue).

    Anyway, thanks for the help you've already given, I appreciate it!
  • ah. Thank you @fcheslack! That helps.

    Everything works fine for me until I try to include authorization. from outside the browser -- say, with postman or curl -- I can easily fetch the resources I want with:

    curl -X GET \
    https://api.zotero.org/users/XXX/items \
    -H 'Authorization: Bearer XXXXXXXXXXXX'

    However, when I try what I think is the fetch equivalent, I'm getting a CORS response:

    let data = await fetch('https://api.zotero.org/users/XXX/items',
    {credentials: 'omit',
    headers: {'Authorization': 'Bearer XXXXXXXX'},
    'withCredentials': true});

    I'm actually shooting in the dark with the 'credentials' and 'withCredentials' options -- I have tried various values of 'credentials' and they all fail.

    The response object from fetch is somewhat complex but has these top-level attributes:

    ok: true
    redirected: false
    status: 200
    statusText: "OK"
    type: "cors"
    url: "https://api.zotero.org/users/20/items"

    If anyone's solved this issue I'd love to hear about how you did it. CORS is somewhat baffling to me so I am a bit lost. Thanks!
  • You don't have to worry about CORS — that's all automatic. This is all you need to do:

    let response = await fetch(
    headers: {
    Authorization: 'Bearer XXXXXXXX'
    var results = await response.json();

    Or for a bibliography:

    let response = await fetch(
    headers: {
    Authorization: 'Bearer XXXXXXXX'
    var bib = await response.text();
  • I'm still getting this:

    Response { type: "cors", url: "https://api.zotero.org/users/20/items", redirected: false, status: 403, ok: false, statusText: "Forbidden", headers: Headers, body: ReadableStream, bodyUsed: false }

  • That just means the API key you're passing doesn't match the userID you're trying to access.
  • (Note that you can and should still use await response.text() to see the response text when you get a 403. For an incorrect key, it would show "Invalid key".)
  • Thanks, Dan. The issue as clearly that I just didn't really understand the fetch API, which I hadn't used before.

    With the addition of the fetch-paginate library, the whole project becomes ridiculously simple. I suppose it could be generalized but here's all the code I really need for my purposes:
    async function getbib () {
    let paginate = await fetchPaginate.default('https://api.zotero.org/users/XXX/collections/XXXX/items/top?include=data,bib&&sort=creator&linkwrap=1&limit=100',
    {options: { headers: {Authorization: 'Bearer XXXXXXXX' }}});
    return paginate.data.reduce((content, item) => {return content + item.bib}, '')
    const output = document.getElementById("output");
    getbib().then (result => {
    output.innerHTML = result;
Sign In or Register to comment.