Skip to content

About

Next.js masonry image gallery component with infinite scroll and tag search, backed by Supabase.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Image Gallery

A masonry gallery page for your own picture collection, with tag search and a full-screen viewer. Add the component to a Next.js app, put image links and tags in Supabase, and you get an endless wall of pictures in random order.

Gallery page with a search box on top and a multi-column masonry grid of illustrations

  • Masonry grid: 2 columns on phones and up to 7 on wide screens, picked from the window width.
  • Endless scroll: 14 more images load as you near the bottom, in random order.
  • Tag search: type a tag in the search box; the query runs 500 ms after you stop typing, and tags must be lowercase.
  • Full-screen viewer: click an image to see it large, rotate it, jump to its tags, and move with arrow keys or swipes.

How it works

Browser (client.jsx) ──► Supabase RPC get_random_media ──► "Gallery" table (image URL + tags)
Browser ──► image URL (any host, e.g. a cloud storage bucket) ──► picture

The images themselves are not stored in Supabase; the table holds only a link, size and tags for each one.

Install

Needs a Next.js app with Tailwind CSS, and a Supabase project. The images must already be hosted somewhere with a public URL.

  1. Install the dependencies: npm install @supabase/supabase-js framer-motion lucide-react
  2. Copy client.jsx into your app and render it from a page, for example import GalleryClient from './client'.
  3. Create lib/supabaseClient.js exporting a supabase client, since the component imports @/lib/supabaseClient. Put NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY in .env.local.
  4. In next.config.js, allow the host of your image URLs under images.remotePatterns, because the full-screen viewer uses Next.js image optimization.
  5. In Supabase, open SQL Editor and create the table. Put the image link in gcs_url and lowercase tags in tags, for example {ln,miku}.
CREATE TABLE public."Gallery" (
  id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
  gcs_url TEXT NOT NULL,
  tags TEXT[] NOT NULL,
  width INT,
  height INT,
  source TEXT
);
  1. Run the second block to create the random-order search function:
CREATE OR REPLACE FUNCTION get_random_media(
  p_search_term text DEFAULT '',
  p_limit int DEFAULT 14,
  p_offset int DEFAULT 0
)
RETURNS TABLE (
  id bigint,
  tags text[],
  width int,
  height int,
  source text,
  gcs_url text,
  created_at timestamptz
)
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
BEGIN
  RETURN QUERY
  SELECT
    m.id,
    COALESCE(m.tags, '{}')::text[],
    m.width,
    m.height,
    m.source,
    m.gcs_url,
    m.created_at
  FROM "Gallery" m
  WHERE
    (p_search_term = '' OR m.tags @> ARRAY[p_search_term]::text[])
  ORDER BY random()
  LIMIT p_limit
  OFFSET p_offset;
END;
$$;

GRANT EXECUTE ON FUNCTION get_random_media(text, int, int) TO anon, authenticated;

Privacy & security

The browser sends search terms to your Supabase project and loads pictures straight from wherever their URLs point. Nothing goes to any other service. The function runs as SECURITY DEFINER and is open to the public anon key, so anyone who has the key can list every row in Gallery. Keep only images you are happy to expose.

License

MIT

About

Next.js masonry image gallery component with infinite scroll and tag search, backed by Supabase.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages