Snug Gallery / Guides

Customer photos and GDPR: what a gallery app stores

What Snug Gallery keeps when a shopper submits a photo, where each piece lives, and how to answer a data access or erasure request in a few minutes.

The moment you let shoppers upload photos to your store, you are collecting personal data from people who are not your customers in Shopify's sense: they may never have placed an order, and they have no customer record for Shopify's privacy tools to act on. Sooner or later one of them writes to ask what you hold about them, or to have their photo taken down. This guide lists exactly what Snug Gallery stores for a customer photo submission, where each piece lives, what is deleted when, and the steps to answer an access or erasure request without guessing.

What the form collects

The submission form on your storefront asks for one image file (JPEG, PNG or WebP, up to 10 MB), an optional display name of up to 80 characters, an optional caption of up to 500 characters, and a consent checkbox that must be ticked. There is no email field and no account requirement, so a submission is not tied to a Shopify customer record unless the shopper happens to type their real name as the display name. The form is only live when customer photos are enabled on that gallery and the store is on a paid plan.

Two things happen to the file before it is stored. The original filename is discarded and replaced with a generated one in the form customer-photo-<timestamp>, so a file called holiday-with-grandma.jpg does not carry that name into your store. And the image bytes are checked against the declared type, so a file that is not actually an image is rejected before anything is written.

Where each piece ends up

The image goes into your store's Files, the same library as every other gallery image, uploaded through Shopify's files API. Snug Gallery's servers handle the bytes in transit and keep no copy. The submission record is an app-owned metaobject in your store with these fields: the gallery it was sent to, the file, the display name, the caption, a status (pending, approved or rejected), the submission time, the consent flag, and a source IP hash. All of that is inside your Shopify store, under your data processing agreement with Shopify, not on a third-party server.

The IP hash deserves a sentence. The form is public, so the app rate-limits it: five submissions per hour from one address, sixty per hour per store. To do that it hashes the shopper's IP address with SHA-256 and a secret salt, keeps the first 32 characters, and uses that as the counter key. The same hash is written to the metaobject so you can spot one person flooding a gallery. It is not reversible without the salt, which the shopper and you do not have, but under GDPR a salted hash of an IP is still pseudonymous personal data, so treat it as such: it is covered by the deletion steps below.

On our own servers, the only thing that touches a submission is the rate-limit table: a row per hashed IP per store with a counter and a window start. Rows older than two windows are swept each time the limiter runs, so a shopper's hash is gone from our side within about two hours of their last attempt. We do not store the image, the name, the caption or the submission record.

What approve, reject and delete do to the data

On the Customer photos page you can approve, reject or delete a submission. Approve copies the item into the gallery as a normal gallery item (file, caption and display name as attribution) and marks the submission approved; the metaobject stays so the record of consent is kept. Reject marks it rejected and removes the file from Files, so the image is gone but the display name, caption, consent and hash remain as a record of what you declined. Delete removes the metaobject and the file permanently.

This matters for erasure requests. If someone asks you to remove their photo and everything about it, reject is not enough, because the name and caption stay in the metaobject. Delete is the action that clears the submission. If the photo was already approved, there is a second copy as a gallery item, and that has to go too; see the steps below.

Answering an access request

  1. Ask the shopper for the display name they used, roughly when they submitted, and which gallery or page it was on. Without an email on the form, those are the only handles you have.
  2. Open Customer photos in Snug Gallery and use the status tabs (Pending, Approved, Rejected) to find the submission. The card shows the display name, caption, submission time and the thumbnail.
  3. If you need the raw record, open Content, Metaobjects in your Shopify admin and look for the app's customer photo entries; each one lists every field above, including the hash and the consent flag.
  4. Reply with what you hold: the image (or that it was removed), the display name, the caption, the time, the fact that they ticked the consent box, and that a salted hash of their IP address at submission time is stored and cannot be reversed. If the photo was approved, add that it is displayed in the gallery named X on page Y.

Answering an erasure request

  1. Find the submission as above. If it is pending or rejected, select it and choose Delete. That removes the metaobject and, for a pending item, the file in Files.
  2. If it was approved, open the gallery in the editor, find the item (approved customer photos keep the display name as their attribution, which makes them easy to spot), and delete the item. Then go back to Customer photos and delete the submission record as well.
  3. Check Content, Files for the image. Rejecting or deleting a submission removes it, and deleting a gallery item removes the item but the file remains in Files as it does for any gallery image. If the file is still there, delete it from Files.
  4. If the shopper's name or likeness appears in a caption on another item, or you reposted the photo to a product page or social media, those copies are yours to remove too; the app does not track them.
  5. Note the date in your records. Nothing on our side needs to be asked for: the rate-limit row has already expired, and there is no other copy.

Shopify's privacy webhooks and what they do here

Shopify sends every app three mandatory privacy webhooks: a customer data request, a customer erasure and a shop erasure. The first two are keyed to a Shopify customer record, and because photo submissions are not tied to a customer, there is nothing for Snug Gallery to return or erase through them; the app acknowledges them and does nothing. That is the honest answer to put in your records if a regulator asks how app data is handled: for this app, customer photo data is managed by you, in your store, with the steps above.

The shop erasure webhook arrives 48 hours after you uninstall. On receipt the app deletes your store's session and every rate-limit row for your store. The metaobjects and files stay in your store under Shopify's own retention for uninstalled apps, as the uninstall guide describes, so the submission records remain yours to delete through the Shopify admin if you leave.

Two lines for your privacy policy

If you run the submission form, your privacy policy should say so. Something like: "Visitors can submit photos to our galleries. We store the photo, the display name and caption they provide, the time of submission, a record of their consent, and a salted, irreversible hash of their IP address used to prevent abuse. Submissions are reviewed before display. To request a copy or removal of a submission, contact us at [address] with the display name used." Adjust the wording to your jurisdiction; the point is that every item in that sentence is something you can actually find and delete, because this guide just showed you where it is.

The moderation guide covers the day-to-day of approving and rejecting; this one is for the day someone asks what you know about them, which, with a public form, is a matter of when.

Frequently asked questions

Does Snug Gallery store customer photos on its own servers?

No. The image is uploaded to your store's Files and the submission record is a metaobject in your store. Our servers only keep a short-lived rate-limit counter keyed by a salted hash of the submitter's IP address, swept within about two hours.

Is a hashed IP address personal data under GDPR?

Treat it as pseudonymous personal data. It cannot be reversed without the secret salt, but it still relates to an identifiable person in principle, so include it in access responses and delete it with the submission. In Snug Gallery it lives in the submission metaobject and is removed when you delete the submission.

If I reject a customer photo, is all their data gone?

Not all of it. Reject removes the image from Files but keeps the metaobject with the display name, caption, consent flag and hash as a record of the decision. To erase everything, use Delete on the Customer photos page, and remove the gallery item too if the photo had been approved.

Will Shopify's customer data request webhook return photo submissions?

No. Those webhooks are keyed to a Shopify customer record, and submissions are not linked to one because the form has no login or email field. The app acknowledges the webhook and reports nothing; you answer the request yourself from the Customer photos page and the metaobject entries in your admin.

More guides