An open-source application for managing your favorite links
Dubsj is a modern, open-source link management application built with Next.js 14+. It provides a clean and intuitive interface for organizing, categorizing, and accessing your favorite links all in one place. Whether you're a developer, researcher, or content creator, Dubsj helps you keep your important URLs organized and easily accessible.
Before you begin, ensure you have the following installed:
git clone https://github.com/surajb1515/dub.sj.git
cd dub.sj
Using npm:
npm install
Using yarn:
yarn install
Using pnpm:
pnpm install
Using bun:
bun install
Create a .env.local file in the root directory:
# App Configuration
NEXT_PUBLIC_APP_URL=http://localhost:3000
# Convex Configuration
CONVEX_DEPLOYMENT=your_convex_deployment_url
NEXT_PUBLIC_CONVEX_URL=your_public_convex_url
# Add other required environment variables
# Install Convex CLI globally
npm install -g convex
# Initialize Convex in your project
npx convex dev
# This will:
# - Create a convex/ directory
# - Set up your Convex deployment
# - Start the Convex dev server
Run the development server:
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
Important: Make sure Convex dev server is also running:
npx convex dev
This will start both your Next.js application and Convex backend in development mode with real-time synchronization.
Open http://localhost:3000 in your browser to see the application.
dub.sj/
├── app/ # Next.js App Router
│ ├── (auth)/ # Authentication routes
│ ├── (dashboard)/ # Dashboard routes
│ ├── api/ # API routes
│ ├── blog/ # Blog pages (MDX)
│ ├── layout.tsx # Root layout
│ └── page.tsx # Home page
├── components/ # React components
│ ├── ui/ # shadcn/ui components
│ ├── layout/ # Layout components
│ └── shared/ # Shared components
├── convex/ # Convex backend
│ ├── schema.ts # Database schema
│ ├── links.ts # Link-related functions
│ ├── auth.ts # Authentication functions
│ └── _generated/ # Auto-generated types
├── content/ # MDX content files
│ └── blog/ # Blog posts
├── lib/ # Utility functions
│ ├── utils.ts # Helper functions
│ └── hooks/ # Custom React hooks
├── public/ # Static assets
│ ├── images/ # Image files
│ └── icons/ # Icon files
├── styles/ # Global styles
│ └── globals.css # Global CSS
├── types/ # TypeScript type definitions
├── .env.local # Environment variables (local)
├── .env.example # Example environment variables
├── convex.json # Convex configuration
├── next.config.js # Next.js configuration
├── tailwind.config.ts # Tailwind CSS configuration
├── tsconfig.json # TypeScript configuration
└── package.json # Project dependencies
Blog posts are written in MDX format and stored in the content/blog/ directory:
.mdx file in content/blog/---
title: "Your Blog Post Title"
description: "A brief description"
date: "2025-01-15"
author: "Your Name"
tags: ["tag1", "tag2"]
---
Your blog content here...
Define your database schema in convex/schema.ts:
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
links: defineTable({
url: v.string(),
title: v.string(),
description: v.optional(v.string()),
category: v.string(),
tags: v.array(v.string()),
userId: v.string(),
createdAt: v.number(),
}).index("by_user", ["userId"]),
categories: defineTable({
name: v.string(),
userId: v.string(),
}).index("by_user", ["userId"]),
});
Create Convex functions in convex/links.ts:
import { query, mutation } from "./_generated/server";
import { v } from "convex/values";
export const getLinks = query({
args: {},
handler: async (ctx) => {
return await ctx.db.query("links").collect();
},
});
export const addLink = mutation({
args: {
url: v.string(),
title: v.string(),
description: v.optional(v.string()),
category: v.string(),
tags: v.array(v.string()),
},
handler: async (ctx, args) => {
const linkId = await ctx.db.insert("links", {
...args,
userId: "current-user-id", // Replace with actual auth
createdAt: Date.now(),
});
return linkId;
},
});
Customize your theme in tailwind.config.ts:
export default {
theme: {
extend: {
colors: {
// Add custom colors
},
// Add other customizations
},
},
plugins: [],
};
Configure Next.js settings in next.config.js:
/** @type {import('next').NextConfig} */
const nextConfig = {
// Add your configurations here
};
module.exports = nextConfig;
The easiest way to deploy your Next.js app with Convex is using Vercel:
Deploy Convex Backend
npx convex deploy
This will give you a production Convex deployment URL.
Push your code to GitHub
Import your repository in Vercel
Configure environment variables in Vercel:
CONVEX_DEPLOYMENT=your_production_convex_deployment
NEXT_PUBLIC_CONVEX_URL=your_production_convex_url
Deploy your application
You can also deploy to:
npm run build
npm run start
Contributions are welcome! Here's how you can help:
git checkout -b feature/amazing-feature
git commit -m 'Add some amazing feature'
git push origin feature/amazing-feature
This project is licensed under the MIT License - see the LICENSE file for details.
Suraj - @surajb1515
Project Link: https://github.com/surajb1515/dub.sj
Made with ❤️ by Suraj