{"id":26863798,"url":"https://github.com/structuredlabs/supawald","last_synced_at":"2026-01-19T22:01:45.002Z","repository":{"id":285294954,"uuid":"955788241","full_name":"StructuredLabs/supawald","owner":"StructuredLabs","description":"Supawald is a headless CMS for Supabase Storage. An out-of-the-box interface for managing files, images, and content in your Supabase Storage buckets with real-time updates and static site generation support. Manage files, set permissions, and connect directly to your Supabase project.","archived":false,"fork":false,"pushed_at":"2025-04-16T19:54:37.000Z","size":4192,"stargazers_count":159,"open_issues_count":0,"forks_count":13,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-09-14T23:36:54.439Z","etag":null,"topics":["cms","content-management","headless","nextjs","npm","supabase","tailwindcss"],"latest_commit_sha":null,"homepage":"https://supawald.com/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/StructuredLabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-03-27T07:43:02.000Z","updated_at":"2025-09-11T17:37:12.000Z","dependencies_parsed_at":null,"dependency_job_id":"7d6631e7-c834-4d7e-b0a1-b28f4a8e9e33","html_url":"https://github.com/StructuredLabs/supawald","commit_stats":null,"previous_names":["structuredlabs/supawald"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/StructuredLabs/supawald","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StructuredLabs%2Fsupawald","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StructuredLabs%2Fsupawald/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StructuredLabs%2Fsupawald/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StructuredLabs%2Fsupawald/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StructuredLabs","download_url":"https://codeload.github.com/StructuredLabs/supawald/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StructuredLabs%2Fsupawald/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28587063,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T20:45:59.482Z","status":"ssl_error","status_checked_at":"2026-01-19T20:45:41.500Z","response_time":67,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cms","content-management","headless","nextjs","npm","supabase","tailwindcss"],"created_at":"2025-03-31T03:32:49.152Z","updated_at":"2026-01-19T22:01:44.996Z","avatar_url":"https://github.com/StructuredLabs.png","language":"TypeScript","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"/template/public/SupawaldBanner.png\" alt=\"Supawald Banner\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cem\u003eA headless CMS for Supabase Storage. Built with Next.js 14, TypeScript, and Tailwind CSS.\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"LICENSE\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/license-Apache%202.0-blue.svg\" alt=\"Apache 2.0 License\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://nodejs.org/\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/node-18%2B-blue.svg\" alt=\"Node.js Version\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://nextjs.org/\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Next.js-14-black\" alt=\"Next.js\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://supabase.com/\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Supabase-Platform-green\" alt=\"Supabase\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n## 🚀 Quick Start with Template\n\n1. **Create a new project**\n   ```bash\n   npx create-supawald my-app\n   cd my-app\n   ```\n\n2. **Set up your Supabase project**\n   - Create a new bucket in Supabase Storage\n   - Get your project URL and anon key from Settings -\u003e API\n   - Copy `.env.example` to `.env.local` and fill in your credentials:\n     ```env\n     NEXT_PUBLIC_SUPABASE_URL=your-project-url\n     NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key\n     NEXT_PUBLIC_BUCKET_NAME=your-bucket-name\n     AUTH_USERNAME=admin\n     AUTH_PASSWORD=your-secure-password\n     ```\n\n3. **Start the development server**\n   ```bash\n   npm install\n   npm run dev\n   ```\n\n4. **Visit http://localhost:3000** and log in with your credentials\n\n\u003e **Note**: The template includes a complete Next.js application with file management, authentication, and static site generation support.\n\n# Supawald\n\nA headless CMS for Supabase Storage. Built with Next.js 14, TypeScript, and Tailwind CSS. Provides a clean interface for managing files in Supabase Storage buckets with real-time updates and static site generation support.\n\n![Supawald Screenshot](/template/public/images/viewbucket.png)\n\n## What is Supawald?\n\nSupawald is a file management system that turns Supabase Storage into a full-featured CMS. It's designed for developers who need a simple way to manage assets for their Next.js applications, blogs, or any project using Supabase Storage.\n\n### Key Features\n\n- **File Management**\n  - Drag \u0026 drop file uploads\n  - Folder navigation\n  - File deletion\n  - In-place file editing\n  - Real-time updates via Supabase subscriptions\n\n- **Developer Experience**\n  - TypeScript for type safety\n  - Next.js 14 App Router\n  - Tailwind CSS for styling\n  - Basic auth protection\n  - Publish API for static site generation\n\n- **Storage Features**\n  - Public/private bucket support\n  - File type detection\n  - File size tracking\n  - Last modified timestamps\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src=\"/template/public/images/viewmarkdown.png\" alt=\"Supawald Screenshot\" width=\"100%\"\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cimg src=\"/template/public/images/viewimage.png\" alt=\"Supawald Screenshot\" width=\"100%\"\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n## Use Cases\n\n1. **Blog Asset Management**\n   - Store and manage images, documents, and other media\n   - Organize content by date, category, or project\n   - Quick access to frequently used assets\n\n2. **Document Management**\n   - Store and organize PDFs, spreadsheets, and other documents\n   - Version control through Supabase's built-in features\n   - Secure access control via bucket policies\n\n3. **Application Assets**\n   - Manage static assets for web applications\n   - Store user uploads and generated content\n   - Handle media files for user profiles or content\n\n## Technical Requirements\n\n- Node.js 18+\n- Supabase account (free tier works)\n- npm or yarn\n\n## ▶️ Quick Start\n\n### Use the CLI\n\n```bash\nnpx create-supawald my-app\ncd my-app\nnpm install\nnpm run dev\n```\n\n### Or clone manually\n\n```bash\ngit clone https://github.com/yourusername/supawald.git\ncd supawald/template\nnpm install\nnpm run dev\n```\n\n2. **Set Up Supabase**\n   ```sql\n   -- Create a new bucket in Supabase Storage\n   -- Name it something like 'blog-content' or 'assets'\n   -- Set appropriate privacy settings (public/private)\n   ```\n\n3. **Configure Environment**\n   ```bash\n   cp .env.example .env.local\n   ```\n   ```env\n   # Supabase\n   NEXT_PUBLIC_SUPABASE_URL=your-project-url\n   NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key\n   NEXT_PUBLIC_BUCKET_NAME=your-bucket-name\n\n   # Auth (for admin access)\n   AUTH_USERNAME=admin\n   AUTH_PASSWORD=your-secure-password\n\n   # Publish API (for static site generation)\n   PUBLISH_URL=https://your-site.com/api/publish\n   PUBLISH_TOKEN=your-secure-token\n   ```\n\n4. **Run Development Server**\n   ```bash\n   npm run dev\n   ```\n\n## Static Site Generation Integration\n\nSupawald includes a publish API that triggers regeneration of static pages that depend on Supabase Storage data. This is useful for:\n- Blog posts that display uploaded images\n- Product pages with product images\n- Any static page that needs to reflect changes in your storage bucket\n\n### Setting Up Your Static Site\n\n1. **Create a Publish API Route**\n   Create a new API route in your Next.js application at `pages/api/publish.ts`:\n\n   ```typescript\n   import { NextApiRequest, NextApiResponse } from 'next'\n\n   export default async function handler(\n     req: NextApiRequest,\n     res: NextApiResponse\n   ) {\n     // Check for secret to confirm this is a valid request\n     if (req.headers.authorization !== `Bearer ${process.env.PUBLISH_TOKEN}`) {\n       return res.status(401).json({ message: 'Invalid token' })\n     }\n\n     try {\n       // Revalidate your static pages\n       await res.revalidate('/') // Revalidate homepage\n       await res.revalidate('/blog') // Revalidate blog pages\n       await res.revalidate('/products') // Revalidate product pages\n       \n       return res.json({ revalidated: true })\n     } catch (err) {\n       // If there was an error, Next.js will continue\n       // to show the last successfully generated page\n       return res.status(500).send('Error revalidating')\n     }\n   }\n   ```\n\n2. **Configure Environment Variables**\n   In your Supawald instance:\n   ```env\n   PUBLISH_URL=https://your-static-site.com/api/publish\n   PUBLISH_TOKEN=your-secure-token\n   ```\n\n   In your static site:\n   ```env\n   PUBLISH_TOKEN=your-secure-token  # Same token as above\n   ```\n\n3. **Using the Publish Button**\n   When you click the publish button in Supawald:\n   - It sends a POST request to your static site's publish API\n   - Your static site regenerates the specified pages\n   - The new content becomes available on your static site\n\n![Supawald Screenshot](/template/public/images/screenshot.png)\n\n\n### Example Usage\n\n```typescript\n// In your static site's page component\nexport async function getStaticProps() {\n  // Fetch data from Supabase Storage\n  const { data: images } = await supabase.storage\n    .from('your-bucket')\n    .list('blog-images')\n\n  return {\n    props: {\n      images,\n      // ... other props\n    },\n    // Revalidate every hour\n    revalidate: 3600\n  }\n}\n```\n\nWhen you update an image in Supawald and click publish:\n1. The image is updated in Supabase Storage\n2. The publish API is called\n3. Your static pages are regenerated with the new image\n4. The changes are live on your static site\n\n## API Integration\n\n### File Operations\n\n```typescript\n// Example: Upload a file\nconst { data, error } = await supabase.storage\n  .from('your-bucket')\n  .upload('path/to/file.jpg', file)\n\n// Example: Get file URL\nconst { data: { publicUrl } } = supabase.storage\n  .from('your-bucket')\n  .getPublicUrl('path/to/file.jpg')\n```\n\n### Static Site Generation\n\n```typescript\n// Trigger static page regeneration\nawait fetch('/api/publish', {\n  method: 'POST',\n  headers: {\n    'Authorization': `Bearer ${process.env.PUBLISH_TOKEN}`\n  }\n})\n```\n\n## 🔒 Security Best Practices\n\n1. **Supabase Storage**\n   - Use private buckets for sensitive content\n   - Implement RLS policies for bucket access\n   - Set up CORS rules for your domain\n   - Use signed URLs for temporary access\n\n2. **Authentication**\n   - Use strong passwords for admin access\n   - Implement rate limiting\n   - Set up proper CORS headers\n   - Use HTTPS in production\n\n3. **Environment Variables**\n   - Never commit `.env.local`\n   - Rotate credentials regularly\n   - Use different keys for development/production\n   - Consider using a secrets manager\n   - Keep your `PUBLISH_TOKEN` secure and only share with trusted services\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Run development server\nnpm run dev\n\n# Build for production\nnpm run build\n\n# Start production server\nnpm start\n```\n\n## **🤝 Contributing**\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for development guidelines.\n\n## **📄 License**\n\nApache 2.0 - See [LICENSE](LICENSE) for details.\n\n## **🎉 Join the Community**\n\n- **GitHub Issues**: Found a bug? Let us know [here](https://github.com/StructuredLabs/supawald/issues).\n- **Community Forum**: Reach out [here](https://join.slack.com/t/structuredlabs-users/shared_invite/zt-31vvfitfm-_vG1HR9hYysR_56u_PfI8Q)\n- **Discussions**: Share your ideas and ask questions in our [discussion forum](https://github.com/StructuredLabs/supawald/discussions).\n\n## **📢 Stay Connected**\n\n\u003cp\u003e\n    \u003ca href=\"https://www.linkedin.com/company/structuredlabs/\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Follow%20Us-LinkedIn-blue?style=for-the-badge\u0026logo=linkedin\" alt=\"Follow us on LinkedIn\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://x.com/StructuredLabs\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Follow%20Us-Twitter-1DA1F2?style=for-the-badge\u0026logo=twitter\" alt=\"Follow us on Twitter\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstructuredlabs%2Fsupawald","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstructuredlabs%2Fsupawald","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstructuredlabs%2Fsupawald/lists"}