1

This query

query MyQuery {
  allStrapiLogos {
    nodes {
      id
      Image {
        localFile {
          publicURL
        }
      }
    }
  }
}

provides the following result:

{
  "data": {
    "allStrapiLogos": {
      "nodes": [
        {
          "id": "Logos_1",
          "Image": [
            {
              "localFile": {
                "publicURL": "someUrl.png"
              }
            },
            {
              "localFile": {
                "publicURL": "someUrl.png"
              }
            }
          ]
        },
        {
          "id": "Logos_2",
          "Image": [
            {
              "localFile": {
                "publicURL": "/someUrl.png"
              }
            }
          ]
        },
        {
          "id": "Logos_3",
          "Image": [
            {
              "localFile": {
                "publicURL": "someUrl.svg"
              }
            }
          ]
        }
      ]
    }
  },
  "extensions": {}
}

Usually, what I did was going on like this:

  <Link to={publicURL}>
          <ReactSVG wrapper="span" src={svgIcons.download} style={{ paddingRight: '16px' }} />
        </Link>

this always worked for 1 file. I am unsure what the best approach would be to tackle downloading multiple images at once.
The GraphQL queries are generated by the gatsby-source-plugin. Any ideas?

Ferran Buireu
  • 28,630
  • 6
  • 39
  • 67
Leviathan
  • 644
  • 1
  • 15
  • 30
  • What's the issue? Can you provide more details? – Ferran Buireu May 31 '21 at 13:22
  • When there is a Logo with multiple image files, I get multiple publicURLs. And a Link component cannot have more than 1 URL it links to. So my issue is that I do not know how a user can download all the images by clicking on a link. Does this make sense? – Leviathan May 31 '21 at 13:57

1 Answers1

0

So my issue is that I do not know how a user can download all the images by clicking on a link.

Given that scenario, I would recommend avoiding the Link component, since doesn't fit your requirements.

I would do something like:

  <button onClick={downloadAllItems}>Download</button>

Then, in your function:

  const downloadAllItems=()=>{
    data.allStrapiLogos.nodes.forEach(node=> window.open(`/yoursite.com/${node.Image.localFile.publicUrl}`))
  }

Modified from:

Add an event.preventDefault before the loop if the button is inside a form to avoid unwanted requests if needed.

Given your use-case, I think is the more intuitive approach to download all items in one-click function.

You can bypass browser's (or adblock's) limitation by setting the window.open and save the memory reference and setting the location on the callback:

let newWindow=window.open(...)

Then:

newWindow.location=`/yoursite.com/${node.Image.localFile.publicUrl}`
Ferran Buireu
  • 28,630
  • 6
  • 39
  • 67
  • 1
    Thank you, yeah I did pretty much exactly what you did. I just hoped there was a better approach, because window.open gets blocked in my own browser already, so this does not seem like a viable option.. Nevertheless, cool that you took the time to reply. I'll sponsor you a coffee tmrw, msg me if I forget it :P – Leviathan May 31 '21 at 20:03
  • I'm glad it helped. Keep in mind that the preferred (standard)way would be to download a single zip file or to create one link per image so given your specifications you need to tweak that logic a bit. I've added a way to bypass browser's limitation – Ferran Buireu Jun 01 '21 at 04:50
  • I have a separate link per image. I mean the publicURL for the download is generated individually during the build process by gatsby. My use case is this: There is a "logo" section, and the client wants that the logos are available in PNG and SVG, and when clicked, both should be downloaded. There also is a "Download all" button. Should the client upload the .zip in the CMS or should I write a function that intercepts the build process and bundles all files into corresponding zips? I'm looking for best practices. – Leviathan Jun 01 '21 at 06:18
  • There's no "best practices" here since it's not a fact that is linked to the code but UX. To me (personal opinion) I'd prefer a zip file (like Google Drive does when downloading multiple assets) rather than downloading multiple items without knowing how many exactly, it's quite invasive for the user. Answering your question, for the user, is more user-friendly that you create the intercept function to create a zip file, rather than forcing the user to do it. But of course, it's up to you – Ferran Buireu Jun 01 '21 at 06:23
  • Man I really hate to be that guy but after googling for 1 hour, two questions: 1) any resource where the zipping/intercepting is explained? 2) I don't understand your "avoid browser" solution. If I change the window reference and it is statically generated, won't only be the last window location be valid? Or I messed up my code :o – Leviathan Jun 01 '21 at 07:39
  • 1) Nope since I don't even know what CMS are you using. 2) Some browser's blocks multiple assets downloading (for security reasons) or the user may have potentially have an adblock extension, so sometimes you get a blank page when you try to download an asset by using `window.open`. The idea is to declare `newWindow` variable and populate the `location` property. Since it's inside the loop, it will be generated in each iteration – Ferran Buireu Jun 01 '21 at 07:43