scaleapi / data-prefetch-link Goto Github PK
View Code? Open in Web Editor NEWExtends next.js <Link> to allow invoking getInitialProps when prefetching a page
License: MIT License
Extends next.js <Link> to allow invoking getInitialProps when prefetching a page
License: MIT License
This package lacks a typescript declaration in @types or its root folder.
next/link
component supports passing an URL object to the href prop, to support it this line:
https://github.com/scaleapi/data-prefetch-link/blob/master/src/link.js#L13
Should be changed to:
const { query } = typeof this.props.href !== 'string'
? this.props.href
: parse(url, true);
I'm getting the same error as in #12 for dynamic pages. (that issue was closed by the poster without solution)
I've created a maximally simple example based off of create-next-app
and then adding 2 simple commits -- the first creating a simple dynamic page, and the second using data-prefetch-link
.
When I execute npm run build
, I get this:
TypeError: Class constructor Link cannot be invoked without 'new'
> Build error occurred
Error: Export encountered errors on following paths:
/
at exportApp (/home/garrett/repro_prefetch_bug/node_modules/next/dist/export/index.js:22:1166)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:85:5)
at async build (/home/garrett/repro_prefetch_bug/node_modules/next/dist/build/index.js:36:218)
Similarly after the build, running npm run start
and visiting http://localhost:3000/
, I get:
~/repro_prefetch_bug $ npm run start
> repro_prefetch_bug@0.1.0 start /home/garrett/repro_prefetch_bug
> next start
ready - started server on http://localhost:3000
TypeError: Class constructor Link cannot be invoked without 'new'
at new DataPrefetchLink (/home/garrett/repro_prefetch_bug/node_modules/data-prefetch-link/dist/link.js:54:79)
at d (/home/garrett/repro_prefetch_bug/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:36:320)
at $a (/home/garrett/repro_prefetch_bug/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:39:16)
at a.b.render (/home/garrett/repro_prefetch_bug/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:44:476)
at a.b.read (/home/garrett/repro_prefetch_bug/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:44:18)
at renderToString (/home/garrett/repro_prefetch_bug/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:54:364)
at render (/home/garrett/repro_prefetch_bug/node_modules/next/dist/next-server/server/render.js:3:298)
at Object.renderPage (/home/garrett/repro_prefetch_bug/node_modules/next/dist/next-server/server/render.js:46:1020)
at Function.getInitialProps (/home/garrett/repro_prefetch_bug/.next/server/static/I4_UWuzN4JT1KYPsHdXK7/pages/_document.js:265:19)
at loadGetInitialProps (/home/garrett/repro_prefetch_bug/node_modules/next/dist/next-server/lib/utils.js:5:101)
I'm unsure where this error is coming from. Not even sure where it came from.
Class constructor Link cannot be invoked without 'new'
TypeError: Class constructor Link cannot be invoked without 'new'
at new DataPrefetchLink (/home/ardeaf/projects/blog/node_modules/data-prefetch-link/dist/link.js:54:79)
at processChild (/home/ardeaf/projects/blog/node_modules/react-dom/cjs/react-dom-server.node.development.js:3182:14)
at resolve (/home/ardeaf/projects/blog/node_modules/react-dom/cjs/react-dom-server.node.development.js:3147:5)
at ReactDOMServerRenderer.render (/home/ardeaf/projects/blog/node_modules/react-dom/cjs/react-dom-server.node.development.js:3631:22)
at ReactDOMServerRenderer.read (/home/ardeaf/projects/blog/node_modules/react-dom/cjs/react-dom-server.node.development.js:3565:29)
at renderToString (/home/ardeaf/projects/blog/node_modules/react-dom/cjs/react-dom-server.node.development.js:4296:27)
at render (/home/ardeaf/projects/blog/node_modules/next/dist/next-server/server/render.js:81:16)
at renderPage (/home/ardeaf/projects/blog/node_modules/next/dist/next-server/server/render.js:283:20)
at ctx.renderPage (/home/ardeaf/projects/blog/.next/server/static/development/pages/_document.js:1711:26)
at /home/ardeaf/projects/blog/.next/server/static/development/pages/_document.js:837:17
at Generator.next (<anonymous>)
at asyncGeneratorStep (/home/ardeaf/projects/blog/.next/server/static/development/pages/_document.js:286:24)
at _next (/home/ardeaf/projects/blog/.next/server/static/development/pages/_document.js:308:9)
at /home/ardeaf/projects/blog/.next/server/static/development/pages/_document.js:315:7
at new Promise (<anonymous>)
at new F (/home/ardeaf/projects/blog/node_modules/core-js/library/modules/_export.js:36:28)
The readme wisely states not to use data-prefetch-link on large lists so as a compromise I would like to do it when a user hovers a link. http://instantclick.io makes traditional sites feel so much faster because there is usually enough of a delay between user intent to click and actual click to start fetching data.
Apollo has an example of prefetching here:
onMouseOver={() => client.query({ query: GET_DOG, variables: { breed: data.breed } }) }
...but the way they do it seems unmaintainable...every link has to know all queries onMouseOver needs for the target page. It seems much better to do what data-prefetch-link does but in onMouseOver and then the getInitialProps on a page can manage queries more locally...something like this:
if(isVirtualCall) { // from data-prefetch-link
client.query(...)
}
Workaround from @adamsoffer ...
Take a look at this: https://shaleenjain.com/blog/nextjs-apollo-prefetch/
You can create “prefetch()” function and invoke it on mouseOver.
import Router from 'next/router'
import { format, resolve, parse } from 'url'
export default prefetch = async (href) => {
// if we're running server side do nothing
if (typeof window === 'undefined') return
const url =
typeof href !== 'string'
? format(href)
: href
const { pathname } = window.location
const parsedHref = resolve(pathname, url)
const { query } =
typeof href !== 'string'
? href
: parse(url, true);
// get component reference
const Component = await Router.prefetch(parsedHref)
// fetch the component props
// and cache locally, handled within getInitialProps
if (Component && Component.getInitialProps) {
const ctx = { pathname: href, query, isVirtualCall: true }
await Component.getInitialProps(ctx)
}
}
Any chance data-prefetch-link would support a hover enable parameter to speed up all those links you may not necessarily want prefetched on page load?
Data prefetching no longer works using the latest next apollo example. I imagine it has something to do with the introduction of _app.js
. Has anyone managed to get it working with the apollo example?
This component is calling Component.getInitialProps always, it doesn't matter if the method is not actually defined which should be checked always to avoid possible issues (maybe logging an error if it's not defined).
https://github.com/scaleapi/data-prefetch-link/blob/master/src/link.js#L16
That should be changed to:
if (
this.props.withData &&
Component &&
Component.getInitialProps &&
typeof Component.getInitialProps === 'function'
)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.