I am trying to migrate node from @prismicio/client v5 to v6

app.js

/* eslint-disable no-undef */
/* eslint-disable no-unused-vars */
require('dotenv').config();

const logger = require('morgan');
const path = require('path');
const express = require('express');
const errorHandler = require('errorhandler');
const bodyParser = require('body-parser');
const methodOverride = require('method-override');

const app = express();
const port = process.env.PORT || 8005;

const Prismic = require('@prismicio/client');
const PrismicDOM = require('prismic-dom');
const { application } = require('express');
const UAParser = require('ua-parser-js');

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(errorHandler());
app.use(methodOverride());
app.use(express.static(path.join(__dirname, 'public')));

// Initialize the prismic.io api
const initApi = (req) => {
  return Prismic.createClient(process.env.PRISMIC_ENDPOINT, {
    accessToken: process.env.PRISMIC_ACCESS_TOKEN,
    req,
  });
};

// Link Resolver
const HandleLinkResolver = (doc) => {
  if (doc.type === 'product') {
    return `/detail/${doc.slug}`;
  }

  if (doc.type === 'collections') {
    return '/collections';
  }

  if (doc.type === 'about') {
    return `/about`;
  }

  // Default to homepage
  return '/';
};

// Middleware to inject prismic context
app.use((req, res, next) => {
  const ua = UAParser(req.headers['user-agent']);

  res.locals.isDesktop = ua.device.type === undefined;
  res.locals.isPhone = ua.device.type === 'mobile';
  res.locals.isTablet = ua.device.type === 'tablet';

  res.locals.Link = HandleLinkResolver;
  res.locals.PrismicDOM = PrismicDOM;
  res.locals.Numbers = (index) => {
    return index === 0
      ? 'One'
      : index === 1
      ? 'Two'
      : index === 2
      ? 'Three'
      : index === 3
      ? 'Four'
      : '';
  };

  next();
});

app.set('view engine', 'pug');
app.set('views', path.join(__dirname, 'views'));
app.locals.basedir = app.get('views');

const handleRequest = async (api) => {
  const meta = await api.getSingle('meta');
  const preloader = await api.getSingle('preloader');
  const navigation = await api.getSingle('navigation');
  const home = await api.getSingle('home');
  const about = await api.getSingle('about');
  const { results: collections } = await api.query( Prismic.Predicates.at('document.type', 'collection'), { fetchLinks: 'product.image' } ); // prettier-ignore

  console.log(about, home, collections);

  const assets = [];

  home.data.gallery.forEach((item) => {
    assets.push(item.image.url);
  });

  about.data.gallery.forEach((item) => {
    assets.push(item.image.url);
  });

  about.data.body.forEach((section) => {
    if (section.slice_type === 'gallery') {
      section.items.forEach((item) => {
        assets.push(item.image.url);
      });
    }
  });

  collections.forEach((collection) => {
    collection.data.products.forEach((item) => {
      assets.push(item.products_product.data.image.url);
    });
  });

  console.log(assets);

  return {
    assets,
    meta,
    home,
    collections,
    about,
    navigation,
    preloader,
  };
};

app.get('/', async (req, res) => {
  const api = await initApi(req);
  const defaults = await handleRequest(api)
    .then((defaults) => {
      if (defaults) {
        res.render('pages/home', {
          ...defaults,
        });
      } else {
        res.status(404).render('404');
      }
    })
    .catch((error) => {
      next(`error when retriving page ${error.message}`);
    });
});

app.get('/about', async (req, res) => {
  const api = await initApi(req);
  const defaults = await handleRequest(api)
    .then((defaults) => {
      if (defaults) {
        res.render('pages/about', {
          ...defaults,
        });
      } else {
        res.status(404).render('404');
      }
    })
    .catch((error) => {
      next(`error when retriving page ${error.message}`);
    });
});

app.get('/collections', async (req, res) => {
  const api = await initApi(req);
  const defaults = await handleRequest(api)
    .then((defaults) => {
      if (defaults) {
        res.render('pages/collections', {
          ...defaults,
        });
      } else {
        res.status(404).render('404');
      }
    })
    .catch((error) => {
      next(`error when retriving page ${error.message}`);
    });
});

// app.get('/detail/:uid', async (req, res) => {
//   const api = await initApi(req);
//   const defaults = await handleRequest(api);

//   const product = await api.getByUID('product', req.params.uid, {
//     fetchLinks: 'collection.title',
//   });

//   if (product) {
//     res.render('pages/detail', {
//       product,
//       ...defaults,
//     });
//   } else {
//     res.status(404).send('Page not found');
//   }
// });

app.get('/detail/:uid', async (req, res) => {
  const api = await initApi(req);
  const product = await api.getByUID('product', req.params.uid, {
    fetchLinks: 'collection.title',
  });
  const defaults = await handleRequest(api)
    .then((defaults) => {
      if (defaults) {
        res.render('pages/detail', {
          ...defaults,
          product,
        });
      } else {
        res.status(404).render('404');
      }
    })
    .catch((error) => {
      next(`error when retriving page ${error.message}`);
    });
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
});

what else i have to change here to make the development work in localhost.
right now i am experiencing this error: crbug/1173575, non-JS module files deprecated.

Screenshot 2565-01-28 at 8.07.52 PM

Screenshot 2565-01-28 at 8.08.07 PM

Hi Ojas,

I'm not exactly sure of what's causing the error, but it's recommended to upgrade from prismic-dom to @prismicio/helpers.

Thanks.

not working :c
here's the app.js the only changement i did was replacing @prismicio/helpers from prismic-dom

/* eslint-disable no-undef */
/* eslint-disable no-unused-vars */
require('dotenv').config();

const logger = require('morgan');
const path = require('path');
const express = require('express');
const errorHandler = require('errorhandler');
const bodyParser = require('body-parser');
const methodOverride = require('method-override');

const app = express();
const port = process.env.PORT || 8005;

const Prismic = require('@prismicio/client');
const PrismicH = require('@prismicio/helpers');
const { application } = require('express');
const UAParser = require('ua-parser-js');

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(errorHandler());
app.use(methodOverride());
app.use(express.static(path.join(__dirname, 'public')));

// Initialize the prismic.io api
const initApi = (req) => {
  return Prismic.createClient(process.env.PRISMIC_ENDPOINT, {
    accessToken: process.env.PRISMIC_ACCESS_TOKEN,
    req,
  });
};

// Link Resolver
const HandleLinkResolver = (doc) => {
  if (doc.type === 'product') {
    return `/detail/${doc.slug}`;
  }

  if (doc.type === 'collections') {
    return '/collections';
  }

  if (doc.type === 'about') {
    return `/about`;
  }

  // Default to homepage
  return '/';
};

// Middleware to inject prismic context
app.use((req, res, next) => {
  const ua = UAParser(req.headers['user-agent']);

  res.locals.isDesktop = ua.device.type === undefined;
  res.locals.isPhone = ua.device.type === 'mobile';
  res.locals.isTablet = ua.device.type === 'tablet';

  res.locals.Link = HandleLinkResolver;
  res.locals.PrismicH = PrismicH;
  res.locals.Numbers = (index) => {
    return index === 0
      ? 'One'
      : index === 1
      ? 'Two'
      : index === 2
      ? 'Three'
      : index === 3
      ? 'Four'
      : '';
  };

  next();
});

app.set('view engine', 'pug');
app.set('views', path.join(__dirname, 'views'));
app.locals.basedir = app.get('views');

const handleRequest = async (api) => {
  const meta = await api.getSingle('meta');
  const preloader = await api.getSingle('preloader');
  const navigation = await api.getSingle('navigation');
  const home = await api.getSingle('home');
  const about = await api.getSingle('about');
  const { results: collections } = await api.query( Prismic.Predicates.at('document.type', 'collection'), { fetchLinks: 'product.image' } ); // prettier-ignore

  console.log(about, home, collections);

  const assets = [];

  home.data.gallery.forEach((item) => {
    assets.push(item.image.url);
  });

  about.data.gallery.forEach((item) => {
    assets.push(item.image.url);
  });

  about.data.body.forEach((section) => {
    if (section.slice_type === 'gallery') {
      section.items.forEach((item) => {
        assets.push(item.image.url);
      });
    }
  });

  collections.forEach((collection) => {
    collection.data.products.forEach((item) => {
      assets.push(item.products_product.data.image.url);
    });
  });

  console.log(assets);

  return {
    assets,
    meta,
    home,
    collections,
    about,
    navigation,
    preloader,
  };
};

app.get('/', async (req, res) => {
  const api = await initApi(req);
  const defaults = await handleRequest(api)
    .then((defaults) => {
      if (defaults) {
        res.render('pages/home', {
          ...defaults,
        });
      } else {
        res.status(404).render('404');
      }
    })
    .catch((error) => {
      next(`error when retriving page ${error.message}`);
    });
});

app.get('/about', async (req, res) => {
  const api = await initApi(req);
  const defaults = await handleRequest(api)
    .then((defaults) => {
      if (defaults) {
        res.render('pages/about', {
          ...defaults,
        });
      } else {
        res.status(404).render('404');
      }
    })
    .catch((error) => {
      next(`error when retriving page ${error.message}`);
    });
});

app.get('/collections', async (req, res) => {
  const api = await initApi(req);
  const defaults = await handleRequest(api)
    .then((defaults) => {
      if (defaults) {
        res.render('pages/collections', {
          ...defaults,
        });
      } else {
        res.status(404).render('404');
      }
    })
    .catch((error) => {
      next(`error when retriving page ${error.message}`);
    });
});

// app.get('/detail/:uid', async (req, res) => {
//   const api = await initApi(req);
//   const defaults = await handleRequest(api);

//   const product = await api.getByUID('product', req.params.uid, {
//     fetchLinks: 'collection.title',
//   });

//   if (product) {
//     res.render('pages/detail', {
//       product,
//       ...defaults,
//     });
//   } else {
//     res.status(404).send('Page not found');
//   }
// });

app.get('/detail/:uid', async (req, res) => {
  const api = await initApi(req);
  const product = await api.getByUID('product', req.params.uid, {
    fetchLinks: 'collection.title',
  });
  const defaults = await handleRequest(api)
    .then((defaults) => {
      if (defaults) {
        res.render('pages/detail', {
          ...defaults,
          product,
        });
      } else {
        res.status(404).render('404');
      }
    })
    .catch((error) => {
      next(`error when retriving page ${error.message}`);
    });
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
});

Do you have this project on Github or could send me a zip to investigate?

thankyou for helping me sir really appreicate your efforts. however here is the repo sir :pray:

OK, so here's the error in the console:

throw new PrismicError("A valid fetch implementation was not provided. In environments where fetch is not available (including Node.js), a fetch implementation must be provided via a polyfill or the `fetch` option.", void 0, void 0);

It explains:

A valid fetch implementation was not provided. In environments where fetch is not available (including Node.js), a fetch implementation must be provided via a polyfill or the fetch option.

That means that for now, and for all previous versions of node, the only way to use fetch in a node environment is to include a polyfill for it or import a library that does so.

My understanding is that express is the library that does this, so I'm not sure why it's throwing this error. I'm trying to get more information on what could be causing this, but in the meantime check out our blog implementation for node.js to see if you can gleam anything that might help.

OK so apparently, you need to explicitly provide fetch:

npm i node-fetch
import fetch from 'node-fetch'
const client = prismic.createClient("repo-name"
  { fetch }
)

This is detailed here:

Hi Ojas,

Thanks for providing your env file I removed it for your privacy. Did you test adding node-fetch in your project like detailed in the link above?

tried but app is crashing again and again :frowning:

error i am getting

[0] node:internal/modules/cjs/loader:1125
[0]       throw new ERR_REQUIRE_ESM(filename, parentPath, packageJsonPath);
[0]       ^
[0] 
[0] Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /Users/desartist22/Documents/GitHub/floema-ice/node_modules/node-fetch/src/index.js
[0] require() of ES modules is not supported.
[0] require() of /Users/desartist22/Documents/GitHub/floema-ice/node_modules/node-fetch/src/index.js from /Users/desartist22/Documents/GitHub/floema-ice/app.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
[0] Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/desartist22/Documents/GitHub/floema-ice/node_modules/node-fetch/package.json.
[0] 
[0]     at new NodeError (node:internal/errors:278:15)
[0]     at Object.Module._extensions..js (node:internal/modules/cjs/loader:1125:13)
[0]     at Module.load (node:internal/modules/cjs/loader:973:32)
[0]     at Function.Module._load (node:internal/modules/cjs/loader:813:14)
[0]     at Module.require (node:internal/modules/cjs/loader:997:19)
[0]     at require (node:internal/modules/cjs/helpers:92:18)
[0]     at Object.<anonymous> (/Users/desartist22/Documents/GitHub/floema-ice/app.js:5:15)
[0]     at Module._compile (node:internal/modules/cjs/loader:1108:14)
[0]     at Object.Module._extensions..js (node:internal/modules/cjs/loader:1137:10)
[0]     at Module.load (node:internal/modules/cjs/loader:973:32) {
[0]   code: 'ERR_REQUIRE_ESM'
[0] }
[0] [nodemon] app crashed - waiting for file changes before starting...

for import i have to give type module in package.json and if i do that then require not gonna work what am i suppose to do here :frowning:

@Phil had solved the error by downgrading the module to version compatible to cjs env :slight_smile: now having this error in /about route and also things are taking time to load

this line is showing as a error in console
.about__content__description!=PrismicDOM.RichText.asHtml(section.primary.description).replace(/<p>/g, '<p data-animation="paragraph">')

[0] GET /about 500 8816.511 ms - 2377
[0] TypeError: /Users/desartist22/Documents/GitHub/floema-ice/views/pages/about.pug:25
[0]     23|                 p.about__content__label(data-animation="label")!=section.primary.label
[0]     24| 
[0]   > 25|                 .about__content__description!=PrismicDOM.RichText.asHtml(section.primary.description).replace(/<p>/g, '<p data-animation="paragraph">')
[0]     26| 
[0]     27|               figure.about__content__media
[0]     28|                 img.about__content__media__image(data-src=section.primary.image.url alt=section.primary.image.alt)
[0] 
[0] Cannot read properties of undefined (reading 'RichText')
[0]     at eval (eval at wrap (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/pug-runtime/wrap.js:6:10), <anonymous>:191:57)
[0]     at eval (eval at wrap (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/pug-runtime/wrap.js:6:10), <anonymous>:387:4)
[0]     at template (eval at wrap (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/pug-runtime/wrap.js:6:10), <anonymous>:402:7)
[0]     at Object.exports.renderFile (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/pug/lib/index.js:454:38)
[0]     at Object.exports.renderFile (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/pug/lib/index.js:444:21)
[0]     at View.exports.__express [as engine] (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/pug/lib/index.js:493:11)
[0]     at View.render (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/express/lib/view.js:135:8)
[0]     at tryRender (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/express/lib/application.js:640:10)
[0]     at Function.render (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/express/lib/application.js:592:3)
[0]     at ServerResponse.render (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/express/lib/response.js:1012:7)

i able to solve the problem where things are taking time to respond :laughing: now only thing which is messing right now is the error from /about route by commenting that line things work :slight_smile:

Hey Ojas,

The issue on line 25 is that you're are calling PrismicDOM for RichText, when now you need to call migrate to Prismic helpers for this:

yes PrismicH but now it complains about asHtml

see this

[0] GET /about 500 4567.837 ms - 2373
[0] TypeError: /Users/desartist22/Documents/GitHub/floema-ice/views/pages/about.pug:25
[0]     23|                 p.about__content__label(data-animation="label")!=section.primary.label
[0]     24| 
[0]   > 25|                 .about__content__description!=PrismicH.RichText.asHtml(section.primary.description).replace(/<p>/g, '<p data-animation="paragraph">')
[0]     26| 
[0]     27|               figure.about__content__media
[0]     28|                 img.about__content__media__image(data-src=section.primary.image.url alt=section.primary.image.alt)
[0] 
[0] Cannot read properties of undefined (reading 'asHtml')
[0]     at eval (eval at wrap (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/pug-runtime/wrap.js:6:10), <anonymous>:191:64)
[0]     at eval (eval at wrap (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/pug-runtime/wrap.js:6:10), <anonymous>:387:4)
[0]     at template (eval at wrap (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/pug-runtime/wrap.js:6:10), <anonymous>:402:7)
[0]     at Object.exports.renderFile (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/pug/lib/index.js:454:38)
[0]     at Object.exports.renderFile (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/pug/lib/index.js:444:21)
[0]     at View.exports.__express [as engine] (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/pug/lib/index.js:493:11)
[0]     at View.render (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/express/lib/view.js:135:8)
[0]     at tryRender (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/express/lib/application.js:640:10)
[0]     at Function.render (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/express/lib/application.js:592:3)
[0]     at ServerResponse.render (/Users/desartist22/Documents/GitHub/floema-ice/node_modules/express/lib/response.js:1012:7)

now it complains about asHtml however i solved that prismic-dom error before only just forgot to aware about that to you

Are you importing prismichelps as primsicH?

It will help me a lot if you always share your code for the page with your error.

yes
here you go with the app.js => file

and this is about.pug => file

I guess you're pulling in the package, but not pulling in all the components like this example:

import * as prismicH from '@prismicio/helpers'

sorry it was mybad idk but i did save my about.pug file and also editor has auto saved on thinks work successfully but it taking time to respond so i tried to... refactor that by fetching them all at once by doing promise.all something like this


const [meta, preloader, navigation, home, about, { results: collections }] =

await Promise.all([

api.getSingle('meta'),

api.getSingle('preloader'),

api.getSingle('navigation'),

api.getSingle('home'),

api.getSingle('about'),

api.query(Prismic.Predicates.at('document.type', 'collection'), {

fetchLinks: 'product.image',

}),

]);

and it worked great but then also it do take some time and idk how i can resolve that :c

what else i can refactor here to make it to optimise it more....

I'm not sure there's any way to optimise this as you're getting all your documents at once. The suggested way would be to break up your queries, like we do in our blog example:

can you explain me in form of the example from my repo? i apologies that this alll is taking somuch time to get my head around with this but the thing i can assure you that it gonna be worth great by seeing the end results :slight_smile: