Skip to content

micha42-dot/Linkkiste_Bookmarks

Repository files navigation

LINK | kiste

A minimalist, self-hosted bookmarking tool inspired by the golden era of del.icio.us.

Built with React 19, Vite, and Supabase. Designed for speed, privacy, and simplicity.

Screenshot

License React Supabase

✨ Features

  • Private by Design: You own the data. It lives in your own Supabase project.
  • Retro Interface: A clean, no-nonsense UI inspired by early 2000s social web.
  • Powerful Organization: Support for both Tags and Folders.
  • Read Later: Mark items as unread to catch up on them later.
  • Personal Notes: Add markdown notes to any bookmark.
  • Full Search: Instantly filter by tag, URL, title, or description.
  • Import/Export: Full data ownership with SQL, CSV, and XML export options.

🛠️ Prerequisites

  • Node.js (v18 or higher)
  • A free Supabase account.

🚀 Installation Guide

1. Setup Backend (Supabase)

Since this is a serverless app, you need to set up your database first.

  1. Create a new project at database.new.
  2. Navigate to the SQL Editor in the sidebar.
  3. Paste and run the following script to create the database schema and security policies:
-- 1. Create the Bookmarks Table
create table bookmarks (
  id bigint generated by default as identity primary key,
  created_at timestamp with time zone default timezone('utc'::text, now()) not null,
  url text not null,
  title text not null,
  description text,
  tags text[] default '{}',
  folders text[] default '{}',
  notes text,
  to_read boolean default false,
  user_id uuid references auth.users not null default auth.uid()
);

-- 2. Enable Row Level Security (RLS)
-- This ensures data is completely private to the logged-in user.
alter table bookmarks enable row level security;

create policy "Users can only see their own bookmarks" on bookmarks for select using (auth.uid() = user_id);
create policy "Users can insert their own bookmarks" on bookmarks for insert with check (auth.uid() = user_id);
create policy "Users can update their own bookmarks" on bookmarks for update using (auth.uid() = user_id);
create policy "Users can delete their own bookmarks" on bookmarks for delete using (auth.uid() = user_id);

-- 3. Setup Storage for Avatars
insert into storage.buckets (id, name, public) values ('avatars', 'avatars', true);

create policy "Avatar images are publicly accessible" on storage.objects for select using ( bucket_id = 'avatars' );
create policy "Anyone can upload an avatar" on storage.objects for insert with check ( bucket_id = 'avatars' AND auth.role() = 'authenticated' );
  1. Go to Project Settings -> API.
  2. Copy the Project URL and the anon public key.

2. Local Development

  1. Clone the repository:

    git clone https://github.com/yourusername/linkkiste.git
    cd linkkiste
  2. Install dependencies:

    npm install
  3. Configure environment variables: Create a file named .env in the root directory:

    VITE_SUPABASE_URL=https://your-project-ref.supabase.co
    VITE_SUPABASE_ANON_KEY=your-long-anon-key-string
  4. Start the app:

    npm run dev

📦 Deployment

You can deploy this for free on Vercel, Netlify, or Cloudflare Pages.

Option A: Vercel (Recommended)

  1. Push your code to GitHub.
  2. Import the project into Vercel.
  3. In the "Environment Variables" section, add:
    • VITE_SUPABASE_URL
    • VITE_SUPABASE_ANON_KEY
  4. Deploy!

⚠️ Important: If the first deployment fails because you forgot the variables, simply adding them isn't enough. You must go to the Deployments tab, click the three dots on the failed deployment, and select Redeploy.

Option B: Cloudflare Pages

  1. Log in to Cloudflare and go to Compute (Workers & Pages) -> Pages.
  2. Click Connect to Git and select your repository.
  3. Build Settings:
    • Framework Preset: Vite
    • Build Command: npm run build
    • Output Directory: dist
  4. Environment Variables: Add your VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY here.

⚠️ Critical: Vite "bakes" environment variables into the code at build time. If you add the variables after the initial build runs (or if the first build fails), you must go to Deployments -> Retry deployment to rebuild the app with the keys included.


🔗 How to Save Links (The "Share Target" Feature)

Okay, here is the honest truth: Since this is a self-hosted private tool, there is no magic "Install" button in the App Store that automatically sets up sharing. You have to wire it up yourself.

🖥️ Desktop (Chrome/Edge/Brave)

This project includes a local browser extension (in the public/extension folder) that lets you save links with one click.

  1. Go to chrome://extensions.
  2. Enable Developer Mode (toggle in top right).
  3. Click Load Unpacked.
  4. Select the public/extension folder inside this project directory.
  5. Click the new icon in your toolbar and enter your App URL (e.g., https://my-linkkiste.vercel.app).

📱 Mobile (Android/iOS)

There is currently no native "Share to LinkKiste" system menu integration out of the box (requires complex PWA manifest configuration).

  1. Open your deployed app in your mobile browser.
  2. Add to Home Screen to install it as a PWA.
  3. To save a link, copy the URL, open LinkKiste, and tap + Add.

🔒 Privacy & Security

This tool is designed to be single-user (or limited user).

  1. Register your account immediately after deployment.
  2. Go to your Supabase Dashboard -> Authentication -> Providers -> Email.
  3. Disable "Confirm email" (unless you want to set up SMTP).
  4. CRITICAL: Once you have created your account, go to Authentication -> Settings -> User Signups and disable "Allow new users to sign up".
    • This prevents random strangers from using your instance as their database.

🤝 Contributing

Feel free to open issues or submit PRs. This is a passion project to keep the spirit of the old web alive.

📄 License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published