routing of nested pages in Gatsby

Viewed 835

I haven't found similar topic corresponding to the challange I have.

I have a gatsby project which creates kind of management portal of the projects. I try to figure out how can I create properly routing among pages. I have a main page which display list of projects. It should be available in URL path "/projects".

Every element of the list suppose to be a link to project's page. I would like to have it in path "/project-number" where number should be dynamic depends on of the project like e.g."/project-1", "/project-2".

Every project should contain 2 sub-pages: map and description with the path e.g."/project-1/map". Both map and description sub-page uses the same Gatsby's Layout and different content depending on the displaying project.

The main page index.js where the path suppose to look "/projects":

import React from "react"

import Layout from "../components/layout"
import SEO from "../components/seo"

import ListOfContent from "../components/listOfContent";
import projects from "../data/projects";

const IndexPage = () => (
    <Layout pageInfo={{pageName: "index"}}>
        <SEO title="Home" />
            <ListOfContent projects={projects}/>
    </Layout>
);

export default IndexPage

listOfContent.js is a component injected in index.js

const ListOfContent = props => {
    const { items } = props.projects;

    const listOfProjects = items.map( Item =>
            <ListGroup.Item key={Item.id} >
                <Image src={Item.customerLogo} className={style.CustomerLogo} />
                <Link to={`/${Item.projectUrlName}/projectPage`}>{Item.projectName}</Link>
            </ListGroup.Item>
    );
    return (
        <ListGroup>
            {listOfProjects}
        </ListGroup>
    )
};

projects.js contains array of projects details

const projects = {
    items: [
        {
            id: uuidv4(),
            projectUrlName: "project-1",
            projectName: "Project-1",
            projectPicture: require('../images/building.png'),
            projectDescription: "{customer_logo}",
            customer: "Name",
            projectPosition: "//www.arcgis.com/apps/Embed/index.html?webmap=...",
        },
        {...},
    ],
};

export default projects;

layout.js

const Layout = ({ children, pageInfo, data }) => {
    const {items} = projects;
    return (
              <>
                <Container fluid className="px-0 main">
                  <Navbar pageInfo={pageInfo} items={items}/>
                  <Row noGutters>
                    <Col>
                      <Container className="mt-5">
                        <main>{children}</main>
                      </Container>
                    </Col>
                  </Row>
                </Container>
              </>
        )}
      />
)};

export default Layout

navbar.js contains dropdown with links to map and description sub-pages

<Navbar.Collapse id="basic-navbar-nav">
          <Nav className="mr-auto" activeKey={props.pageInfo && pageName}>
              <NavDropdown title={projectName} id="collapsible-nav-dropdown">
                  <NavDropdown.Item><Link to="map" activeClassName="active">map</Link></NavDropdown.Item>
                  <NavDropdown.Item><Link to="description" activeClassName="active">description</Link></NavDropdown.Item>
          </Nav>

description.js is a sub-page of the a single project where the path suppose to look "/project-1/map"

const DescriptionPage = () => (
  <Layout pageInfo={{ pageName: "description" }}>
    <SEO title="Project description" />
    <h1>project name</h1>
    <p>description</p>
  </Layout>
);

export default DescriptionPage

My challanges are:

  1. How to create dynamic path which will include number of the project "/project-number"
  2. How can I use components description.js and map.js (similar to description.js) as a templates where would be dynamicaly incjected content from projects.js. In other words, I want to have only one map.js and one description.js in the folder src/pages/map.js which will show different content depends on chosen project on the index.js.
  3. map.js and description.js have to have path "/project-1/map", "/project-2/map", etc.
0 Answers
Related