{"id":26063189,"url":"https://github.com/wiidede/exif-gallery-nuxt","last_synced_at":"2026-04-18T08:02:29.643Z","repository":{"id":275533763,"uuid":"926356140","full_name":"wiidede/exif-gallery-nuxt","owner":"wiidede","description":"A free personal photo gallery (nuxt + nuxthub) deployable on Cloudflare, with AI image analysis and browser-side image compression  可免费部署在 Cloudflare 的个人相册网站，支持AI图像分析，浏览器压缩图片","archived":false,"fork":false,"pushed_at":"2026-03-31T19:53:43.000Z","size":2507,"stargazers_count":113,"open_issues_count":2,"forks_count":22,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-31T21:37:30.276Z","etag":null,"topics":["cloudflare","exif","gallery","nuxt","nuxthub","photos","r2"],"latest_commit_sha":null,"homepage":"https://photo.wiidede.space","language":"Vue","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wiidede.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-02-03T05:13:27.000Z","updated_at":"2026-03-31T19:53:48.000Z","dependencies_parsed_at":"2025-02-28T12:23:45.834Z","dependency_job_id":"c989faca-d6d0-4836-a54b-127610c8e57e","html_url":"https://github.com/wiidede/exif-gallery-nuxt","commit_stats":null,"previous_names":["wiidede/exif-gallery-nuxt"],"tags_count":0,"template":false,"template_full_name":"Flosciante/nuxt-image-gallery","purl":"pkg:github/wiidede/exif-gallery-nuxt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wiidede%2Fexif-gallery-nuxt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wiidede%2Fexif-gallery-nuxt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wiidede%2Fexif-gallery-nuxt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wiidede%2Fexif-gallery-nuxt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wiidede","download_url":"https://codeload.github.com/wiidede/exif-gallery-nuxt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wiidede%2Fexif-gallery-nuxt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31961348,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T00:39:45.007Z","status":"online","status_checked_at":"2026-04-18T02:00:07.018Z","response_time":103,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["cloudflare","exif","gallery","nuxt","nuxthub","photos","r2"],"created_at":"2025-03-08T16:32:29.819Z","updated_at":"2026-04-18T08:02:29.628Z","avatar_url":"https://github.com/wiidede.png","language":"Vue","funding_links":[],"categories":["Vue"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# EXIF Gallery Nuxt\n\n**A free personal photo gallery deployable on Cloudflare, with AI image analysis and browser-side image compression**\n\n[English](README.md) | [简体中文](README_zh.md)\n\n[![Cloudflare Workers](https://img.shields.io/badge/Cloudflare-Workers-F38020?style=for-the-badge\u0026logo=cloudflare\u0026logoColor=white)](https://workers.cloudflare.com/)\n[![Nuxt](https://img.shields.io/badge/Nuxt-4.0-00DC82?style=for-the-badge\u0026logo=nuxt.js\u0026logoColor=white)](https://nuxt.com/)\n[![Vue](https://img.shields.io/badge/Vue-3.5-4FC08D?style=for-the-badge\u0026logo=vue.js\u0026logoColor=white)](https://vuejs.org/)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.0-3178C6?style=for-the-badge\u0026logo=typescript\u0026logoColor=white)](https://www.typescriptlang.org/)\n[![License](https://img.shields.io/badge/License-MIT-green?style=for-the-badge)](LICENSE)\n\n\u003c/div\u003e\n\n---\n\n![exif-gallery-nuxt](./public/exif-gallery-nuxt.jpg)\n\n## ✨ Features\n\n- 🆓 **Free Cloudflare Deployment** - Zero-cost hosting on Cloudflare Workers with generous free tier\n- 🧠 **AI-Powered Image Intelligence** - Integration with OpenAI and Gemini for semantic analysis and intelligent image descriptions\n- 🖼️ **Smart Image Processing** - Browser-side compression supporting JPEG, WebP, and AVIF formats with automatic thumbnail generation\n- 💾 **Edge-Native Storage** - Cloudflare R2 object storage with D1 database for optimal performance and global edge deployment\n- 📊 **Complete EXIF Management** - Full extraction and display of image metadata including camera settings, location data, and timestamps\n- 🏷️ **Flexible Tagging System** - Organize photos with custom tags and filter by categories\n- 📑 **Sorting \u0026 Pagination** - Sort photos and smooth pagination\n- 🎨 **Modern User Experience** - Responsive design with smooth view transitions and beautiful UI components\n- 🔐 **Secure Admin Panel** - Built-in authentication system for secure photo management and uploads\n\n## 🚀 Quick Start\n\n### Prerequisites\n\n- [Node.js](https://nodejs.org/) 18.x or higher\n- [pnpm](https://pnpm.io/) (recommended)\n\n```bash\n# Install pnpm (if not already installed)\ncorepack enable pnpm\n\n# Clone the repository\ngit clone https://github.com/wiidede/exif-gallery-nuxt.git\ncd exif-gallery-nuxt\n\n# Install dependencies\npnpm install\n\n# Start development server\npnpm dev\n```\n\nVisit `http://localhost:3000` to see the application.\n\n## 🛠️ Tech Stack\n\n- **Framework**: [Nuxt 4](https://nuxt.com/) - The Intuitive Vue Framework\n- **Edge Platform**: [NuxtHub](https://hub.nuxt.com) - Build fullstack applications on the edge\n- **Database**: [D1](https://developers.cloudflare.com/d1/) - SQLite at the edge\n- **Storage**: [R2](https://developers.cloudflare.com/r2/) - S3-compatible object storage\n- **Styling**: [UnoCSS](https://unocss.dev/) - The instant on-demand atomic CSS engine\n- **UI Components**: [shadcn-vue](https://www.shadcn-vue.com/) + [inspira-ui](https://inspira-ui.com/)\n- **State Management**: [Pinia](https://pinia.vuejs.org/)\n- **Validation**: [vee-validate](https://vee-validate.logaretm.com/) + [Zod](https://zod.dev/)\n- **AI**: [OpenAI](https://openai.com/) + [Google Gemini](https://gemini.google.com/)\n- **Code Quality**: [TypeScript](https://www.typescriptlang.org/) + [ESLint](https://eslint.org/)\n\n## 📦 Deployment\n\n### Deploy to Cloudflare Workers\n\nThis project is designed for deployment on Cloudflare Workers with NuxtHub.\n\n#### Step 1: Create Cloudflare Resources\n\n1. **Create D1 Database**\n   - Navigate to **Storage \u0026 Databases** → **D1 SQL Database** in Cloudflare Dashboard\n   - Create a database named `exif-gallery-nuxt` and note the **Database ID**\n\n2. **Create R2 Bucket**\n   - Navigate to **Storage \u0026 Databases** → **R2 Object Storage**\n   - Create a bucket and note the **bucket name**\n\n#### Step 2: Configure Deployment\n\nUpdate `wrangler.jsonc` with your Cloudflare resource IDs:\n\n```jsonc\n{\n  \"d1_databases\": [\n    {\n      \"binding\": \"DB\",\n      \"database_name\": \"exif-gallery-nuxt\",\n      \"database_id\": \"YOUR_DATABASE_ID\",\n      \"migrations_dir\": \"server/db/migrations/sqlite\",\n      \"migrations_table\": \"_hub_migrations\"\n    }\n  ],\n  \"r2_buckets\": [\n    {\n      \"binding\": \"BLOB\",\n      \"bucket_name\": \"YOUR_BUCKET_NAME\"\n    }\n  ]\n}\n```\n\n#### Step 2.5: Initialize Database\n\n**Important**: Cloudflare D1 database cannot be connected during build, so migrations are **not automatically applied**. You must manually run migrations to create the table structure.\n\n**Using GitHub Actions (Recommended, Automated)**\n\nThe project includes a `.github/workflows/migrate.yml` file. You can:\n\n1. Add the following secrets in your GitHub repository settings:\n   - `CLOUDFLARE_ACCOUNT_ID` - Your Cloudflare account ID (visible in Cloudflare Dashboard)\n   - `CLOUDFLARE_API_TOKEN` - API token with D1 edit permissions (create at Cloudflare Dashboard → My Profile → API Tokens)\n\n2. Push code to the `main` branch, or manually trigger the `Database Migration` workflow in GitHub Actions\n\n\u003e [!NOTE]\n\u003e This project adopts a separated migration management strategy:\n\u003e\n\u003e - Local Development: Migrations are automatically managed by NuxtHub and recorded in the `_hub_migrations` table.\n\u003e - Cloud Deployment: Migrations are managed via GitHub Actions using Wrangler, also recorded in the `_hub_migrations` table, but with an additional `.sql` file extension compared to NuxtHub migrations.\n\u003e - Note: Do not manually run Wrangler migration commands during local development, as those files lack the `.sql` suffix.\n\n#### Step 3: Deploy via Cloudflare Dashboard\n\n1. Go to **Workers \u0026 Pages** → **Create application** → **Connect to Git**\n2. Select your forked repository\n3. Configure build settings:\n   - **Build command**: `pnpm run build`\n   - **Deploy command**: `npx wrangler deploy`\n4. Add environment variables:\n   - `NUXT_SESSION_PASSWORD` - Generate a secure random string (at least 32 characters)\n   - `NUXT_ADMIN_PASSWORD` - Set your admin panel password\n5. Click **Deploy**\n\nNuxtHub will automatically configure D1 and R2 bindings based on `wrangler.jsonc`.\n\n### Manual Deployment\n\n```bash\n# Build for production\npnpm run build\n\n# Deploy to Cloudflare Workers\nnpx wrangler deploy\n```\n\n### Remote Development\n\nConnect to your remote Cloudflare resources locally:\n\n```bash\npnpm dev --remote\n```\n\n### Migration from NuxtHub Admin\n\nFor users who previously deployed using NuxtHub Admin:\n\n1. **Update your fork** to get the latest changes:\n\n2. **Get existing resources** from your NuxtHub project:\n   - D1 database ID\n   - R2 bucket name\n\n3. **Update `wrangler.jsonc`** with your existing resources:\n\n   ```jsonc\n   {\n     \"d1_databases\": [{ \"binding\": \"DB\", \"database_id\": \"YOUR_EXISTING_DATABASE_ID\" }],\n     \"r2_buckets\": [{ \"binding\": \"BLOB\", \"bucket_name\": \"YOUR_EXISTING_BUCKET_NAME\" }]\n   }\n   ```\n\n   Commit and push this change.\n\n4. **Create new Worker** by following steps 2-3 in the deployment section above\n\n5. **Configure environment variables** from your old project\n\n6. **Deploy** - your data remains in the same D1 database and R2 bucket\n\n## 🔧 Configuration\n\n### Environment Variables\n\n| Variable                              | Required | Default                                                                                                                       | Description                                                             |\n| ------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |\n| `NUXT_ADMIN_PASSWORD`                 | Yes      | `admin`                                                                                                                       | Admin panel access password                                             |\n| `NUXT_SESSION_PASSWORD`               | Yes      | --                                                                                                                            | Session encryption key(at least 32 characters)                          |\n| `NUXT_PUBLIC_TITLE`                   | No       | `Exif Gallery Nuxt`                                                                                                           | Application title                                                       |\n| `NUXT_PUBLIC_DESCRIPTION`             | No       | `A full-stack photo album solution that integrates AI intelligent processing, browser image compression, and other functions` | Application description                                                 |\n| `NUXT_PUBLIC_DISABLE_3D_CARD_DEFAULT` | No       | `false`                                                                                                                       | Whether to disable 3D card effect by default (set to `true` to disable) |\n\n## 📁 Project Structure\n\n```\nexif-gallery-nuxt/\n├── app/                    # Frontend application\n│   ├── components/         # Vue components\n│   ├── composables/       # Vue composables\n│   ├── pages/             # Application pages\n│   ├── stores/            # Pinia stores\n│   ├── utils/             # Utility functions\n│   └── workers/           # Web Workers\n├── server/                # Backend API\n│   ├── api/               # API routes\n│   ├── db/                # Database schema\n│   └── utils/             # Server utilities\n└── types/                 # TypeScript definitions\n```\n\n## 🤝 Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to the branch (`git push origin feature/AmazingFeature`)\n5. Open a Pull Request\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## 🙏 Acknowledgments\n\n- [exif-photo-blog](https://github.com/sambecker/exif-photo-blog) - Inspiration for EXIF handling\n- [nuxt-image-gallery](https://github.com/Flosciante/nuxt-image-gallery) - Gallery implementation reference\n- [NuxtHub](https://hub.nuxt.com) - Edge deployment platform\n- [shadcn-vue](https://www.shadcn-vue.com/) - Beautiful UI components\n- [inspira-ui](https://inspira-ui.com/) - Animated UI components\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\nMade with ❤️ by [wiidede](https://github.com/wiidede)\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwiidede%2Fexif-gallery-nuxt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwiidede%2Fexif-gallery-nuxt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwiidede%2Fexif-gallery-nuxt/lists"}