6

I am building an LMS using Next.js. So far my project structure is localhost/courses/1. Every course will have 7 pages. Dashboard, Assignment, TestAndQuizzes, Gradebook, Resources, Announcements, and Roster. I have all the components and pages ready. So if I manually go to localhost/courses/1/assignments or localhost/courses/1323/roster, etc. works fine.

What I want to do is: When I click on the assignment link, I need to go to the assignment page of that specific course - something like localhost/courses/1/assignments. Currently, I have hard-coded the URL to /courses/1/[page] so if I click assignments it will go to localhost/courses/1/assignment or if I click roster it will go to localhost/courses/1/roster.

How do I make that route dynamic so that when users click on one of the tabs inside a course, it takes them to that page of that specific course?

I looked up next/link and next/router but I still am not able to do that. Any help?

Edit: Here is my folder structure:

enter image description here

Like I said above, for now I have used the links to send someone to /courses/1/assignment for example.

If you want to check out the site it is hosted at My app.

import Image from 'next/image';
import tools from "./sidebarData";
import SideBarItem from "./SidebarItem";

function Sidebar() {
    return (
        <div className="flex mt-8 ml-20">
            <div className="">
                <ul>
                    {Object.entries(tools).map(([key, {title, url, icon}]) => (
                        <SideBarItem key={key} title={title} Icon={icon} url={url}/>
                    ))}
                </ul>

            </div>
        </div>
    )
}

export default Sidebar;

import Link from 'next/link';
import {useState, useEffect} from 'react';

function SidebarItem({title, Icon, url}) {

    const [currentUrl, setCurrentUrl] = useState('');
    
    useEffect(() => {
        setCurrentUrl(window.location.href);
    }), [];

    return (
        <div>
            <li className="flex mb-8 group">
                <div className="shadow-sm p-2 mr-3 rounded-lg"><Icon className="h-8 w-9 hover:animate-bounce" /></div>
                <Link href={`${url}`} ><a className="self-center cursor-pointer transition duration-100 transform hover:scale-125">{title}</a></Link>
            </li>
        </div>
    )
}

export default SidebarItem;

// export tool names and URLs
import {
    AcademicCapIcon,
    HomeIcon,
    BookOpenIcon,
    UserGroupIcon,
    SpeakerphoneIcon,
    FolderOpenIcon,
    QuestionMarkCircleIcon

} from "@heroicons/react/outline";

export default{
    goToHome:{
        title: 'Home',
        url: '/courses/1/',
        icon: HomeIcon,
        component : "dashboard"
    },
    goToAsignments:{
        title: 'Assignments',
        url: '/courses/1/assignments',
        icon: AcademicCapIcon,
        component : "assignment"
    },
    goToTestQuizzes:{
        title: 'Test and Quizzes',
        url: '/courses/1/testAndQuizzes',
        icon:QuestionMarkCircleIcon,
        component : "testAndQuizzes"
    },
    goToGradeBook:{
        title: 'Gradebook',
        url: '/courses/1/gradebook',
        icon:BookOpenIcon,
        component : "gradebook"
    },
    goToResources:{
        title: 'Resources',
        url: '/courses/1/resources',
        icon: FolderOpenIcon,
        component : "resources"
    },
    goToAnnouncements:{
        title: 'Announcements',
        url: '/courses/1/announcements',
        icon:SpeakerphoneIcon,
        component : "announcements"
    },
    goToRoster:{
        title: 'Roster',
        url: '/courses/1/roster',
        icon:UserGroupIcon,
        component : "roster"
    },
}

0

2 Answers 2

3

In your JSON data replace the hardcoded course IDs in the url fields with [courseId], e.g. /courses/[courseId] or /courses/[courseId]/assignments.

You can then use a URL object format in the Link's href to interpolate the [courseId] in the URLs with the current course ID retrieved from router.query.

import Link from 'next/link';
import { useRouter } from 'next/router';

function SidebarItem({ title, Icon, url }) {
    const router = useRouter();

    return (
        <div>
            <li className="flex mb-8 group">
                <div className="shadow-sm p-2 mr-3 rounded-lg"><Icon className="h-8 w-9 hover:animate-bounce" /></div>
                <Link href={{
                    pathname: url,
                    query: { courseId: router.query.courseId }
                }}>
                    <a className="self-center cursor-pointer transition duration-100 transform hover:scale-125">{title}</a>
                </Link>
            </li>
        </div>
    );
}

This should make all links in the sidebar dynamic, based on the current course page the user is on.

Sign up to request clarification or add additional context in comments.

1 Comment

the new client side router does not support this anymore.. see nextjs.org/docs/messages/app-dir-dynamic-href
-1

I would recommend you look at the built in dynamic routing https://nextjs.org/docs/routing/dynamic-routes

In your file structure you can specify your dynamic routing with folders like pages/courses/[id]/assignments.jsx make sure you have the folder name exactly like [id] so its dynamic

1 Comment

I just added a picture of my folder structure. And I do have [courseId] as the dynamic folder inside the courses folder. The links that are to be clicked are in a Sidebar component. Do you wanna look at the picture and see if I can do something better there?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.