{"id":21354401,"url":"https://github.com/samestrin/url-shortening-api-netlify-edge-supabase","last_synced_at":"2026-05-16T21:03:15.382Z","repository":{"id":239822455,"uuid":"800278975","full_name":"samestrin/url-shortening-api-netlify-edge-supabase","owner":"samestrin","description":"A TypeScript Netlify Edge Function/Supabase based URL shortener REST API. (This was the original API for https://frwrd.ing/)","archived":false,"fork":false,"pushed_at":"2024-05-18T21:06:55.000Z","size":48,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-16T05:23:59.190Z","etag":null,"topics":["deno","netlify","netlify-edge","netlify-edge-functions","netlify-functions","netlify-lambda","typescript","url-shortener","url-shortener-microservice"],"latest_commit_sha":null,"homepage":"https://frwrd.ing","language":"TypeScript","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/samestrin.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}},"created_at":"2024-05-14T03:17:14.000Z","updated_at":"2024-11-06T19:24:02.000Z","dependencies_parsed_at":"2024-05-18T22:21:56.265Z","dependency_job_id":"851890cc-6700-4130-93c9-ba9dac983d05","html_url":"https://github.com/samestrin/url-shortening-api-netlify-edge-supabase","commit_stats":null,"previous_names":["samestrin/url-shortening-api-netlify-edge-supabase"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/samestrin/url-shortening-api-netlify-edge-supabase","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samestrin%2Furl-shortening-api-netlify-edge-supabase","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samestrin%2Furl-shortening-api-netlify-edge-supabase/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samestrin%2Furl-shortening-api-netlify-edge-supabase/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samestrin%2Furl-shortening-api-netlify-edge-supabase/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/samestrin","download_url":"https://codeload.github.com/samestrin/url-shortening-api-netlify-edge-supabase/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samestrin%2Furl-shortening-api-netlify-edge-supabase/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264403826,"owners_count":23602623,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["deno","netlify","netlify-edge","netlify-edge-functions","netlify-functions","netlify-lambda","typescript","url-shortener","url-shortener-microservice"],"created_at":"2024-11-22T04:13:18.730Z","updated_at":"2026-05-16T21:03:15.298Z","avatar_url":"https://github.com/samestrin.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# url-shortening-api-netlify-edge-supabase\n\n[![Star on GitHub](https://img.shields.io/github/stars/samestrin/url-shortening-api-netlify-edge-supabase?style=social)](https://github.com/samestrin/url-shortening-api-netlify-edge-supabase/stargazers)[![Fork on GitHub](https://img.shields.io/github/forks/samestrin/url-shortening-api-netlify-edge-supabase?style=social)](https://github.com/samestrin/url-shortening-api-netlify-edge-supabase/network/members)[![Watch on GitHub](https://img.shields.io/github/watchers/samestrin/url-shortening-api-netlify-edge-supabase?style=social)](https://github.com/samestrin/url-shortening-api-netlify-edge-supabase/watchers)\n\n![Version 0.0.2](https://img.shields.io/badge/Version-0.0.2-blue)[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)[![Built with Node.js](https://img.shields.io/badge/Built%20with-Node.js-green)](https://nodejs.org/)\n\nurl-shortening-api-netlify-edge-supabase is a URL shortener service. It is a serverless application that provides URL shortening and retrieval functionalities. Utilizing Netlify Edge Functions and Supabase, a cloud-based database, the application offers a high performance, efficient and scalable solution for creating short URLs that redirect to the original, longer URLs.\n\n### Why Netlify Edge Functions?\n\nNetlify Edge Functions are run at the network edge, closer to your users, translating into faster load times. Netlify also offers **1M/month Edge Function executions per month at the free tier**, a significant increase over 125k/month Function executions allocated at the same tier. At the Pro level you have 2m/month to work with.\n\n### Benefits of Edge Functions:\n\n- **Decreased latency**: Running logic closer to the end user can reduce not only the volume of data, but the distance that data needs to travel. If a user were sending a request in Arizona, a response time from a local node would be lower than one in London.\n- **Reduction in cold start boot times**: For serverless functions, cold start boot times average anywhere from 50-500ms on average. The cold start average for edge functions, on the other hand, is drastically reduced (50-200ms).\n\n_This replaces the legacy [url-shortening-api-netlify-supabase](https://github.com/samestrin/url-shortening-api-netlify-supabase) project._\n\n### **Features**\n\n- **URL Shortening**: Convert long URLs into short, manageable links that are easier to share.\n- **URL Validation**: Ensures that only valid URLs with proper protocols are processed.\n- **URL Redirection**: Redirect users to the original long URL based on the short URL.\n- **Link Tracking**: Track which short URLs are served.\n- **Retrieve Latest Shortened URLs**: Access the most recently created short URLs.\n- **URL Count**: Get the total number of URLs shortened.\n- **API Versioning**: Retrieve the current version of the API.\n- **CORS Support**: Handle cross-origin resource sharing with appropriate headers.\n- **Error Handling**: Graceful error handling with appropriate HTTP status codes and error messages.\n\n### **Dependencies**\n\n- **Node.js**: The script runs in a Node.js environment.\n- **Deno**: A secure runtime for JavaScript and TypeScript.\n- **Supabase (REST API)**: A backend-as-a-service providing a Postgres database, authentication, storage, and more.\n- **Netlify Edge Functions**: Serverless functions that run at the edge, closer to your users.\n- **multiParser**: Parses multipart form data.\n\n### **Installation**\n\nTo set up the project locally, follow these steps:\n\n1.  **Clone the Repository**:\n\n```bash\ngit clone https://github.com/samestrin/url-shortening-api-netlify-edge-supabase.git\ncd url-shortening-api-netlify-edge-supabase\n```\n\n2.  **Install Dependencies**: Ensure you have the required dependencies installed. Use npm or yarn to install any necessary packages.\n\n```bash\nnpm install\n```\n\n3.  **Set Up Netlify CLI**: Install the Netlify CLI to deploy and test the functions locally.\n\n```bash\n\nnpm install -g netlify-cli\n```\n\n4. **Configure Environment Variables**: Create a `.env` file in the project root and define `SUPABASE_URL` and `SUPABASE_ANON_KEY` with your Supabase project credentials. Optionally set `URLSHORT_URL_BASE` to your hostname (example: https://frwrd.ing/), and `URLSHORT_TRACK_CLICKS` to `true` to enable short link click tracking.\n\n5. **Run the Functions Locally**: Use the Netlify CLI to run the edge functions locally.\n\n```bash\nnetlify dev\n```\n\n### **Configuration**\n\nThe `netlify.toml` file contains the configuration for the edge functions. Each function is mapped to a specific endpoint:\n\n```toml\n[build]\n  publish = \"public\"\n\n[build.environment]\n  NODE_VERSION = \"20\"\n\n[[edge_functions]]\n  path = \"/shorten\"\n  function = \"shorten\"\n\n[[edge_functions]]\n  path = \"/count\"\n  function = \"count\"\n\n[[edge_functions]]\n  path = \"/latest\"\n  function = \"latest\"\n\n[[edge_functions]]\n  path = \"/version\"\n  function = \"version\"\n\n[[edge_functions]]\n  path = \"/*\"\n  function = \"redirect\"\n\n```\n\n## Endpoints\n\n### Shorten URL\n\n**Endpoint:** `/shorten` **Method:** POST\n\nShorten a long URL and return the shortened URL.\n\n- `url`: The URL to be shortened.\n\n#### **Example Usage**\n\nUse a tool like Postman or curl to make a request:\n\n```bash\ncurl -X POST \\\n  https://localhost/shorten \\\n  -H 'Content-Type: application/x-www-form-urlencoded' \\\n  --data-urlencode 'url=https://www.google.com'\n```\n\nThe server responds with:\n\n```bash\n{\"shortUrl\":\"lqywv6P\"}\n```\n\n### Forward URL\n\n**Endpoint:** `/[shortId]` **Method:** GET\n\nBased on shortened URL, e.g. `/lqywv6P` HTTP 301 forward to a long url.\n\nThis endpoint is accessed by navigating directly to the shortened URL.\n\n#### **Example Usage**\n\nUse curl to make a request:\n\n```bash\ncurl http://localhost/[shortId]\n```\n\n### Retrieve Latest Shortened Links\n\n**Endpoint:** `/latest` **Method:** GET\n\nRetrieve the latest URLs shortened.\n\nThis endpoint is accessed by navigating directly to /latest.\n\n#### **Example Usage**\n\nUse curl to make a request:\n\n```bash\ncurl http://localhost/latest\n```\n\n### Retrieve Count\n\n**Endpoint:** `/count` **Method:** GET\n\nRetrieve the number of URLs shortened.\n\nThis endpoint is accessed by navigating directly to /count.\n\n#### **Example Usage**\n\nUse curl to make a request:\n\n```bash\ncurl http://localhost/count\n```\n\n### Retrieve Version\n\n**Endpoint:** `/version` **Method:** GET\n\nRetrieve the current version of the API.\n\nThis endpoint is accessed by navigating directly to /version.\n\n#### **Example Usage**\n\nUse curl to make a request:\n\n```bash\ncurl http://localhost/version\n```\n\nThe server responds with:\n\n```bash\n{\n    \"name\": \"url-shortening-api-netlify-edge-supabase\",\n    \"version\": \"0.0.1\",\n    \"description\": \"url-shortening-api-netlify-edge-supabase is a URL shortener service using Netlify Edge Functions and the Supabase REST API.\",\n    \"author\": \"Sam Estrin\",\n    \"homepage\": \"https://github.com/samestrin/url-shortening-api-netlify-edge-supabase#readme\"\n}\n```\n\n## CORS\n\nThe server responds with appropriate CORS headers such as Access-Control-Allow-Origin.\n\n## Error Handling\n\nThe API handles errors gracefully and returns appropriate error responses:\n\n- **400 Bad Request**: Invalid request parameters.\n- **404 Not Found**: Resource not found.\n- **405 Method Not Allowed**: Invalid request method (not GET or POST).\n- **500 Internal Server Error**: Unexpected server error.\n\n## Contribute\n\nContributions to this project are welcome. Please fork the repository and submit a pull request with your changes or improvements.\n\n## License\n\nThis project is licensed under the MIT License - see the LICENSE file for details.\n\n## Share\n\n[![Twitter](https://img.shields.io/badge/X-Tweet-blue)](https://twitter.com/intent/tweet?text=Check%20out%20this%20awesome%20project!\u0026url=https://github.com/samestrin/url-shortening-api-netlify-edge-supabase) [![Facebook](https://img.shields.io/badge/Facebook-Share-blue)](https://www.facebook.com/sharer/sharer.php?u=https://github.com/samestrin/url-shortening-api-netlify-edge-supabase) [![LinkedIn](https://img.shields.io/badge/LinkedIn-Share-blue)](https://www.linkedin.com/sharing/share-offsite/?url=https://github.com/samestrin/url-shortening-api-netlify-edge-supabase)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamestrin%2Furl-shortening-api-netlify-edge-supabase","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsamestrin%2Furl-shortening-api-netlify-edge-supabase","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamestrin%2Furl-shortening-api-netlify-edge-supabase/lists"}