top of page
  • Writer's pictureRobert Hebert

How to Create a Project Portfolio Using Dynamic Pages in Wix

Who is our client and what problem did they want to solve?

Our client is a Top 5 U.S. solar developer.

They wanted a project portfolio on their website to showcase all of their projects and the companies that were involved in the process.

The issue is that with the number of projects that they wanted to display, a typical page-by-page build for each project would be extremely time-consuming and difficult to maintain as design changes to the individual project pages are inevitable.

What solution did we provide?

Our solution to solve these issues was to utilize dynamic pages to build the portfolio.

What does that mean?

We were going to have 1 look/template to represent a project page, then populate it with dynamic content from a content database (or in this case, it's called a content manager).

This content database looks like a table, very similar to something you would see while using Excel or any other spreadsheet.

The user will have a row in that table for each project, and columns that represent the different sections the user wants to be displayed on the page.

For example, One column may represent a project's main image. The client will then upload the main image for each project in each row.

The issue of displaying company names and logos on the main project portfolio page and the individual project pages was a tricky solve.

Since some companies (or "offtakers") were needing to display on multiple projects, we felt like it made sense to create an Offtakers table in the Wix Content Manager. Then we made an "offtaker" field in the Projects table that was a "reference field". The first "issue" we ran into was that while this is the proper way to relate the data was that Wix's default dynamic page dataset does not fetch reference fields. So on the projects list page, we had to use the 'wix-data' API's 'queryReferenced' function to retrieve the "offtaker" for each project and their logo. This way we could add them to the main project portfolio page and display the offtaker's name and logo image on the individual project pages.

What happens when you can only display 12 pages in a dynamic list? Wix Dynamic Dataset's API to the rescue!

The second issue we ran into was that the default Wix dynamic list page can only retrieve a max of 12 pages and they had way more projects to list than that. Wix Dynamic Dataset's API to the rescue! On the Project list page, we made two buttons for pagination, a previous button and a next button. Each button when clicked would call either the dynamic dataset's 'hasNextPage' or 'hasPreviousPage' function to check if there was a next or previous page, and if so would then call the 'nextPage' or 'previousPage' function. If the dataset didn't have a previous page, the previous button would be disabled, and if the dataset did not have a next page, then the next page button was disabled.

This pattern was used on the individual project pages, which normally come with next/previous buttons. However, when we first tried to use them they didn't work. After some debugging, it turns out that when the dynamic pages were created they still contained the default "title" field that content manager tables start with. This field was deleted after we had added the fields that we were going to use for the Project table but for some reason, there was still a "filter" on the dataset that was trying to filter on the non-existent "title" field which was preventing Wix from finding the next / previous pages. Once the filter was removed, boom! the next / previous project buttons worked!

Check out the code we used below:

import wixData from 'wix-data';

$w.onReady(async function () {

    const data = $w("#dynamicDataset").getCurrentItem();

    $w("#mwdc").text = `${data.mwDc} MW(DC)`;

    if (typeof data.queueNumber !== 'undefined') {
        $w("#queueNumber").text = `Queue Number: ${data.queueNumber}`;
    } else {
    const offtaker = await wixData.queryReferenced("Projects", data._id, "offtakers", { suppressAuth: true }).then(results => results.items[0]).catch(err => err);

    $w("#offtakerName").text =;
    $w("#offtakerLogo").fitMode = "fit";
    $w("#offtakerLogo").src = offtaker.logoImage;


Interested in setting up something like this for your website? Contact us at 225-250-1888 or email

About our company

RHM specializes in helping businesses of all sizes and across all industries achieve their digital and web marketing needs. Whether you are designing a new website, building an app, performing custom development, or running Google Ads, our goal is to showcase how you are the best at what you do and help people connect with you. Contact us at 225-250-1888 to get started!

389 views0 comments


bottom of page