Redirecting Issue with Shortened URLs - Possible Database/Query Issue

I’m facing an issue with the URL shortening feature in my application. it work fine in localhost, Specifically, valid shortCode entries are sometimes redirecting to incorrect URLs. I suspect there might be an issue with the way the database is handling the shortCode field or how the query logic is retrieving the URLs.

Here’s a quick summary of the problem:

Problem: When a user tries to access a shortened URL (e.g., https://shorty-sigma.vercel.app/73E8YKP), the app redirects to the wrong URL instead of original URL. (NAVIGATING TO SAME WEBSITE/URL THAT GENERATED THE CODE) What I’ve Checked: The shortCode entries in the database appear to be correct. Environment variables seem to be set up correctly since authentication and other features are working fine. The URL shortening process generates and saves shortCode as expected, but the retrieval goes wrong. developing with nextjs deployed to vercel.

import { GetServerSideProps } from 'next';

import dbConnect from '../utils/dbConnect';

import Url from '../models/Url';


// this to handle the URL redirection based on a shortCode parameter.

export const getServerSideProps: GetServerSideProps = async (context) => {
    try {
        await dbConnect();

        const { shortCode } = context.params;
        console.log('Fetching URL for shortCode:', shortCode);
        const urlEntry = await Url.findOne({ shortCode }).exec();
        console.log('URL Entry:', urlEntry);

        // use tenary operator that determines the value of the baseUrl variable 
        // based on the environment in which the application is running. Here's a breakdown of what it does:
        if (urlEntry) {
            const originalUrl = urlEntry.originalUrl.startsWith('http')
                ? urlEntry.originalUrl
                : `http://${urlEntry.originalUrl}`;
            console.log('Redirecting to:', originalUrl);

            return {
                redirect: {
                    destination: originalUrl,
                    permanent: false,
                },
            };
        } else {
            console.log('No URL entry found for shortCode:', shortCode);
            return {
                notFound: true,
            };
        }
    } catch (error) {
        console.error('Error in getServerSideProps:', error);
        return {
            notFound: true,
        };
    }
};

const RedirectPage = () => {
    return null;
};

export default RedirectPage;

**pages/api/shorten.ts - Manages the URL shortening process and database interaction.**

import { NextApiRequest, NextApiResponse } from 'next';

import { nanoid } from 'nanoid';

import QRCode from 'qrcode';

import dbConnect from '../../utils/dbConnect';

import Url from '../../models/Url';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
    await dbConnect();

    // The code fetches the original URL from the database

    if (req.method === 'POST') {
        const { originalUrl, customDomain, customUrl } = req.body;

        if (!originalUrl || typeof originalUrl !== 'string') {
            return res.status(400).json({ error: 'Invalid URL' });
        }

        try {

            // he nanoid library is used to generate a short code. 
            // The base URL is determined by checking if the environment is production

            let shortCode = customUrl || nanoid(7);
            const baseUrl = process.env.NODE_ENV === 'production'
                ? process.env.NEXTAUTH_URL
                : 'http://localhost:3000';

            const shortUrl = customDomain
                ? `${customDomain}/${shortCode}`
                : `${baseUrl}/${shortCode}`;

            // generates a QR code for the shortened URL.

            const qrCode = await QRCode.toDataURL(shortUrl);

            const newUrl = new Url({
                originalUrl,
                shortUrl,
                shortCode,
                qrCode,
            });

            await newUrl.save();

            res.status(201).json({ message: 'URL shortened successfully', shortUrl, qrCode });
        } catch (error) {
            console.error('Error saving URL:', error);
            res.status(500).json({ message: 'Internal Server Error' });
        }
    } else {
        res.status(405).json({ message: 'Method not allowed' });
    }
}

 **utils/dbConnect.ts - Handles the database connection logic** 

import mongoose from 'mongoose';

const MONGODB_URI: string = process.env.MONGODB_URI as string;

if (!MONGODB_URI) {
    throw new Error('Please define the MONGODB_URI environment variable inside .env.local');
}

let cached = (global as any).mongoose;

if (!cached) {
    cached = (global as any).mongoose = { conn: null, promise: null };
}

async function dbConnect() {
    if (cached.conn) {
        return cached.conn;
    }

    if (!cached.promise) {
        const opts = {
            bufferCommands: false,
        };

        cached.promise = mongoose.connect(MONGODB_URI, opts).then((mongoose) => mongoose);
    }
    cached.conn = await cached.promise;
    return cached.conn;
}

export default dbConnect;

**env.local - Environment variables setup (with sensitive information redacted)**

  MONGODB_URI=mongodb+srv://user:password@cluster0.mongodb.net/myDatabase?retryWrites=true&w=majority

  NEXTAUTH_URL=https://shorty-sigma.vercel.app/

  GOOGLE_CLIENT_ID=1234567890-abcde1234.apps.googleusercontent.com

  GOOGLE_CLIENT_SECRET=ABCDEF1234567890

  GITHUB_CLIENT_ID=gh1234567890abcdef

  GITHUB_CLIENT_SECRET=ghabcdef1234567890

  EMAIL_USER=myemail@example.com

  EMAIL_PASS=myemailpassword

  JWT_SECRET=myjwtsecretkey

  NEXTAUTH_SECRET=myNextAuthSecretKey


**NOTE: the env.local values are generated for demonstration purpose except for NEXTAUTH_URL**

import mongoose, { Schema, Model, Document } from 'mongoose';

interface IUrl extends Document {
    originalUrl: string;
    shortUrl: string;
    shortCode: string;
    qrCode: string;
    customUrl?: string;
    customDomain?: string;
    userId: Schema.Types.ObjectId;
    createdAt: Date;
}

const UrlSchema: Schema = new Schema<IUrl>({
    originalUrl: { type: String, required: true },
    shortUrl: { type: String, required: true, unique: true },
    shortCode: { type: String, required: true, unique: true },
    qrCode: { type: String },
    userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
    customDomain: { type: String },
    customUrl: { type: String },
    createdAt: { type: Date, default: Date.now }

}, { timestamps: true });
const Url: Model<IUrl> = mongoose.models.Url || mongoose.model<IUrl>('Url', UrlSchema);
export default Url

the app is working fine in localhost, error/bug occurs when deployed to vercel

can tou help here as well please?
@amyegan
@pawlean

thanks

Hi @umarfaroukpa. Do you see the expected URL in the console.log when you attempt to read it from the database? You should be able to see it in the runtime logs for the deployment.

the expected URL are visible in the database, but can find any in RUNTIME LOGS

Do you see any runtime logs when the serverless function is run? You can click the row to open a side panel with more details about that log item.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.