Skip to content

Repository files navigation


Project Banner
react.js appwrite tailwindcss

Short Freely - A full-stack URL shortner application

Visit Website
A full-stack web application that allows users to create shortened URLs from long URLs with additional features like custom slugs, QR code generation, and link analytics. Built using React, Appwrite, and Tailwind CSS.
  1. Introduction
  2. Tech Stack
  3. Features
  4. UI Designs
  5. Setup & Installation
  6. Usage
  7. Routes & Endpoints
  8. Data Modeling
  9. Directory structure
  10. Deployment

A full-stack web application that allows users to create shortened URLs from long URLs with additional features like custom slugs, QR code generation, and link analytics. Built using React, Appwrite, and Tailwind CSS.

The Problem

In today’s digital age, individuals and businesses frequently share long, unwieldy URLs across various communication channels, such as social media, emails, and messaging platforms. These lengthy URLs can create multiple challenges.

The Solution

The goal is to build a modern, user-friendly full-stack URL shortener application that empowers users to convert long URLs into concise, shareable links. This application bridges the gap between simplicity and functionality, providing a robust platform for URL shortening, analytics, and management. It is designed to focus on good UI/UX, ensuring its relevance and adaptability for evolving user needs.


πŸš€ Tech Stacks

Design & Planning

  • Figma: For designing and prototyping the basic web layout for web.

Frontend

  • React: For building a responsive and interactive user interface.
  • Tailwind CSS: For styling and layout.
  • Redux Toolkit: For state management and efficient data flow.
  • React Router Dom: For routing inside react app.
  • React Hook Form: For building scalable forms and form validations.
  • Motion: Also known as Framer motion for animating react jsx.
  • Ua Parser js: The Essential Web Development Tool for User-Agent Detection.
  • Recharts: For visualizing analytics data in the dashboard.

Backend

  • Appwrite: For database, authentication, and API management.

πŸš€ Features

  • πŸ‘‰ Authentication System: A robust authentication system ensuring security and user privacy.
  • πŸ‘‰ User-friendly Dashboard: User will be provided a Dashboard where he/she can manage account, created short urls and its analytics.
  • πŸ‘‰ Shorten URLs: Convert long URLs into short, easy-to-share links.
  • πŸ‘‰ Custom Slugs: Define custom back-halves for your links (e.g., https://short.ly/custom-slug).
  • πŸ‘‰ URL Redirect: Redirect users to the original URL when they visit the shortened link. Example: Visiting https://yourapp.com/abc123 takes the user to https://example.com/very-long-url.
  • πŸ‘‰ Detailed URL Page: A detailed URL page displaying content and URL Analytics for an immersive user experience.
  • πŸ‘‰ Edit & Delete Functionality: Provide users with the ability to edit and delete the existing URL at any time.
  • πŸ‘‰ QR Code Generation: Automatically generate QR codes for shortened links.
  • πŸ‘‰ Performence Analytics: Track user activity, including device, OS, location, and browser.
  • πŸ‘‰ Best UI/UX: Focused on best UI/UX for the users.
  • πŸ‘‰ Backend as a Service (BaaS) - Appwrite: Utilize Appwrite as a Backend as a Service solution for streamlined backend development, offering features like authentication, database, file storage, and more.

πŸš€ UI Designs

Home Page

Home Page

Auth Page

Form

Dashboard Page

QR Code

List o URLs Page

QR Code

Popups

QR Code

Prerequisites

  1. Node.js (v16+ recommended) and npm installed.
  2. An Appwrite instance running locally or hosted.
  3. Vercel account for deployment (optional).

Clone Repository

git clone https://github.com/SujoyKrHaldar/Short-freely.git
cd url-shortener

Install Dependencies

npm install

Configure Environment Variables

Create a .env file in the root directory and add the following:

VITE_CLIENT_URL = http://localhost:5173
VITE_APPWRITE_URL = https://appwrite.io/v1
VITE_APPWRITE_PROJECT_ID=
VITE_APPWRITE_DATABASE_ID=
VITE_APPWRITE_URL_COLLECTION_ID=
VITE_APPWRITE_ANALYTIC_COLLECTION_ID=
VITE_GET_LOCATION_API_URL= "https://ipapi.co/json"

Start Development Server

npm run dev

The app will run locally at http://localhost:5173.


πŸš€ Usage

Create Shortened URLs

  1. Enter the long URL in the Destination URL field.
  2. Optionally, add a custom title or slug.
  3. A QR code generation will be generated based on Destination URL.
  4. Click the Create button to generate your shortened link.

Query Parameters Support

You can prefill the Destination URL using query parameters:

  1. For loggedin users
/dashboard/create?longurl=https://example.com
  1. For Public users it will look like this for better User Experience
/login?redirectTo=/dashboard/create?longurl=https://example.com

View QR Code

A QR code will appear below the form after pasting Destination URL. You can download it for sharing or copy short url as well.


Overview of routes and their functionality in the application.

Frontend

  1. Public Routes (Accessible without authentication)
Route Description Example URL Features
GET / Landing page with an overview of the app and a form for shortening URLs. https://your-app.com/ - Input field for entering long URLs.
- Option to customize the short URL slug (if allowed).
GET /redirect/:shortUrlSlug Redirects users to the original long URL. https://your-app.com/redirect/xYz123 - Handles redirection to the original URL.
- Tracks click metrics (if implemented).
GET /404 Page displayed when a user accesses an invalid route or slug. https://your-app.com/404 - Informs users about invalid URLs.
GET /login User login page. https://your-app.com/login - Allows users to log in to their accounts.
GET /register User registration page. https://your-app.com/register - Facilitates user account creation.

  1. Private Routes (Accessible after authentication)
Route Description Example URL Features
GET /dashboard Displays a user's shortened URLs, stats, and quick actions. https://your-app.com/dashboard - List of all created short URLs.
- Options to copy, edit, or delete a URL.
- View click stats.
POST /dashboard/create Form for creating a new shortened URL. https://your-app.com/dashboard/create - Option to enter the original URL.
- Custom slug or auto-generate.
- Set an expiration date (optional).
GET /dashboard/edit/:urlId Edit an existing shortened URL. https://your-app.com/dashboard/edit/xYz123 - Modify the original URL or slug.
- Update the expiration date or other metadata.
GET /dashboard/:urlId Displays analytics for a specific short URL. https://your-app.com/dashboard/xYz123 - Click count, geographic data, referral sources.
GET /dashboard/account Manage account settings. https://your-app.com/dashboard/account - Update profile information.
- Change password.

Appwrite Backend API Endpoints

API Endpoint Description Example
/v1/databases/{databaseId}/collections/{collectionId}/documents Create Short URL - Create a document with original URL, slug, and optional metadata.
/v1/databases/{databaseId}/collections/{collectionId}/documents Fetch All URLs - Retrieve all documents representing URLs in the collection.
/v1/databases/{databaseId}/collections/{collectionId}/documents/{documentId} Delete URL - Remove a specific document representing a URL by its ID.

πŸš€ Data Modeling

There will be two collection 1. URL 2. Analytics we will wonk on.

User Collection

Tracks analytics data for each click on a shortened URL.

Field Type Description
_id ObjectId Unique identifier for the user entry.
name String Full name of the user.
email String User's email address (unique).
password String Hashed password.
clickedAt Date Account creation timestamp..
updatedAt Date Last profile update timestamp.

URLs Collection

Stores information about shortened URLs.

Field Type Description
_id ObjectId Unique identifier for the shortened URL.
originalUrl String The full URL provided by the user.
shortUrl String The shortened URL slug .
userId ObjectId Reference to the user who created the URL (null if public).
clickCount Number Total number of clicks on the shortened URL.
qrCode String Path or URL to the generated QR code (auto generated).
customSlug String Custom slug for short URL (optional & unique).
createdAt Date Timestamp of URL creation.
updatedAt Date Timestamp of last modification.

Analytics Collection

Tracks analytics data for each click on a shortened URL.

Field Type Description
_id ObjectId Unique identifier for the analytics entry.
urlId ObjectId Reference to the shortened URL.
ipAddress String IP address of the user clicking the URL.
userAgent String Browser/OS/device information.
location String Geolocation data based on IP (e.g., country, state, city).
clickedAt Date Timestamp of the click.
shortUrl String Short url provided.

Relationships

Relationship Type Description
Users β†’ URLs One-to-Many A user can create multiple shortened URLs.
URLs β†’ Analytics One-to-Many A shortened URL can have multiple analytics entries (one for each click).

Directory structure/
    β”œβ”€β”€ .env.example
    β”œβ”€β”€ index.html
    β”œβ”€β”€ eslint.config.js
    β”œβ”€β”€ public/
    β”œβ”€β”€ postcss.config.js
    β”œβ”€β”€ vercel.json
    β”œβ”€β”€ package.json
    β”œβ”€β”€ vite.config.js
    β”œβ”€β”€ README.md
    β”œβ”€β”€ tailwind.config.js
    └── src/
        β”œβ”€β”€ api/
        β”‚   β”œβ”€β”€ urlService.js
        β”‚   β”œβ”€β”€ authService.js
        β”‚   β”œβ”€β”€ analyticService.js
        β”‚   └── initServer.js
        β”œβ”€β”€ App.jsx
        β”œβ”€β”€ state/
        β”‚   β”œβ”€β”€ auth/
        β”‚   β”‚   β”œβ”€β”€ authSlice.js
        β”‚   β”‚   └── authAction.js
        β”‚   β”œβ”€β”€ notification/
        β”‚   β”‚   β”œβ”€β”€ notificationSlice.js
        β”‚   β”‚   └── notificationAction.js
        β”‚   β”œβ”€β”€ rootReducer.js
        β”‚   β”œβ”€β”€ index.js
        β”‚   └── store.js
        β”œβ”€β”€ assets/
        β”‚   β”œβ”€β”€ svgs/
        β”‚   β”‚   └── Logo.jsx
        β”‚   β”œβ”€β”€ illustrations/
        β”œβ”€β”€ components/
        β”‚   β”œβ”€β”€ layouts/
        β”‚   β”‚   β”œβ”€β”€ index.jsx
        β”‚   β”‚   β”œβ”€β”€ main/
        β”‚   β”‚   β”‚   β”œβ”€β”€ MobNavbar.jsx
        β”‚   β”‚   β”‚   β”œβ”€β”€ MainLayout.jsx
        β”‚   β”‚   β”‚   β”œβ”€β”€ Header.jsx
        β”‚   β”‚   β”‚   β”œβ”€β”€ Footer.jsx
        β”‚   β”‚   β”‚   └── Navbar.jsx
        β”‚   β”‚   └── dashboard/
        β”‚   β”‚       β”œβ”€β”€ DashboardLayout.jsx
        β”‚   β”‚       β”œβ”€β”€ DashboardHeader.jsx
        β”‚   β”‚       └── DashboardSidebar.jsx
        β”‚   β”œβ”€β”€ shared/
        β”‚   β”‚   β”œβ”€β”€ index.jsx
        β”‚   β”‚   └── MetaTags.jsx
        β”‚   β”œβ”€β”€ ui/
        β”‚   β”‚   β”œβ”€β”€ index.jsx
        β”‚   β”‚   β”œβ”€β”€ forms/
        β”‚   β”‚   β”‚   β”œβ”€β”€ Input.jsx
        β”‚   β”‚   β”‚   β”œβ”€β”€ SignupForm.jsx
        β”‚   β”‚   β”‚   └── LoginForm.jsx
        β”‚   β”‚   └── notification/
        β”‚   β”‚       β”œβ”€β”€ NotificationCard.jsx
        β”‚   β”‚       └── NotificationUi.jsx
        β”‚   └── pages/
        β”‚       β”œβ”€β”€ dashboard/
        β”‚       β”‚   β”œβ”€β”€ index.jsx
        β”‚       β”‚   β”œβ”€β”€ search/
        β”‚       β”‚   β”‚   └── DeshboardSearch.jsx
        β”‚       β”‚   β”œβ”€β”€ short-links/
        β”‚       β”‚   β”‚   └── DashboardShortLinks.jsx
        β”‚       β”‚   β”œβ”€β”€ create-url/
        β”‚       β”‚   β”‚   └── DashboardCreateShortUrl.jsx
        β”‚       β”‚   β”œβ”€β”€ url-details/
        β”‚       β”‚   β”‚   β”œβ”€β”€ DashboardUrlDetails.jsx
        β”‚       β”‚   β”‚   β”œβ”€β”€ DashboardUrlAnalytics.jsx
        β”‚       β”‚   β”‚   β”œβ”€β”€ DashboardUrlOptions.jsx
        β”‚       β”‚   β”‚   └── DashboardSingleUrlPage.jsx
        β”‚       β”‚   β”œβ”€β”€ shared/
        β”‚       β”‚   β”‚   β”œβ”€β”€ DashboardLinkCard.jsx
        β”‚       β”‚   β”‚   β”œβ”€β”€ DashboardBreadcrumb.jsx
        β”‚       β”‚   β”‚   β”œβ”€β”€ charts/
        β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ LineChartComponent.jsx
        β”‚       β”‚   β”‚   β”‚   β”œβ”€β”€ PieChartComponent.jsx
        β”‚       β”‚   β”‚   β”‚   └── BarChartComponent.jsx
        β”‚       β”‚   β”‚   β”œβ”€β”€ ShareLinkPopup.jsx
        β”‚       β”‚   β”‚   β”œβ”€β”€ NoResultFallbackUi.jsx
        β”‚       β”‚   β”‚   β”œβ”€β”€ LinkDeletePopup.jsx
        β”‚       β”‚   β”‚   β”œβ”€β”€ ErrorFallbackUi.jsx
        β”‚       β”‚   β”‚   └── DashbaordLinkForm.jsx
        β”‚       β”‚   β”œβ”€β”€ edit-url/
        β”‚       β”‚   β”‚   └── DashboardEditUrl.jsx
        β”‚       β”‚   β”œβ”€β”€ home/
        β”‚       β”‚   β”‚   β”œβ”€β”€ DashboardHomeUrlLists.jsx
        β”‚       β”‚   β”‚   └── DashboardHome.jsx
        β”‚       β”‚   └── account/
        β”‚       β”‚       β”œβ”€β”€ DashboardProfileEdit.jsx
        β”‚       β”‚       β”œβ”€β”€ DashboardAccount.jsx
        β”‚       β”‚       β”œβ”€β”€ DashboardSessions.jsx
        β”‚       β”‚       β”œβ”€β”€ DashboardAccountEditTemplate.jsx
        β”‚       β”‚       └── DashboardPasswordUpdate.jsx
        β”‚       └── home/
        β”‚           β”œβ”€β”€ HomeTestimonialSection.jsx
        β”‚           β”œβ”€β”€ index.jsx
        β”‚           β”œβ”€β”€ HomeLandingSection.jsx
        β”‚           β”œβ”€β”€ HomeFeatureSection.jsx
        β”‚           β”œβ”€β”€ HomeProductUsedBySection.jsx
        β”‚           β”œβ”€β”€ HomeFooterSection.jsx
        β”‚           β”œβ”€β”€ HomeFaqSection.jsx
        β”‚           └── HomeAboutSection.jsx
        β”œβ”€β”€ styles/
        β”‚   └── index.css
        β”œβ”€β”€ hooks/
        β”‚   β”œβ”€β”€ index.jsx
        β”‚   β”œβ”€β”€ useQueryParams.jsx
        β”‚   β”œβ”€β”€ useAuth.jsx
        β”‚   β”œβ”€β”€ useFetchUrlById.jsx
        β”‚   β”œβ”€β”€ useLogout.jsx
        β”‚   β”œβ”€β”€ useFetchUrls.jsx
        β”‚   └── useNotification.jsx
        β”œβ”€β”€ main.jsx
        β”œβ”€β”€ config/
        β”‚   └── index.js
        β”œβ”€β”€ routes/
        β”‚   β”œβ”€β”€ index.jsx
        β”‚   β”œβ”€β”€ PrivateRoutes.jsx
        β”‚   β”œβ”€β”€ PublicRoutes.jsx
        β”‚   └── AuthRoutes.jsx
        β”œβ”€β”€ pages/
        β”‚   β”œβ”€β”€ index.jsx
        β”‚   β”œβ”€β”€ auth/
        β”‚   β”‚   β”œβ”€β”€ Login.jsx
        β”‚   β”‚   └── Signup.jsx
        β”‚   β”œβ”€β”€ public/
        β”‚   β”‚   β”œβ”€β”€ RedirectUrl.jsx
        β”‚   β”‚   β”œβ”€β”€ Home.jsx
        β”‚   β”‚   └── PageNotFound.jsx
        β”‚   └── private/
        β”‚       β”œβ”€β”€ SearchLinks.jsx
        β”‚       β”œβ”€β”€ Account.jsx
        β”‚       β”œβ”€β”€ EditShortUrl.jsx
        β”‚       β”œβ”€β”€ CreateShortUrl.jsx
        β”‚       β”œβ”€β”€ AllShortLinks.jsx
        β”‚       β”œβ”€β”€ Dashboard.jsx
        β”‚       └── UrlDetails.jsx
        β”œβ”€β”€ router.jsx
        └── utils/
            β”œβ”€β”€ imageUrls.js
            └── constants.js

πŸš€ Deployment

Deploying Frontend

  1. Build the React app:
    npm run build
  2. Deploy the build folder to Vercel or any static hosting service.

Deploying Backend

  1. Host your Appwrite instance on a platform like Render or AWS or use their cloud service for free for better experience.
  2. Configure your database and collection settings in Appwrite.

Enjoy building your own URL Shortener! πŸš€

About

Short-freely - a URL shortner full stack web application

Topics

Resources

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages