Reputation: 1
I'm having some issues with Astro/React and rendering a component in production. I'm using react-youtube in a tsx component and then turning it into an .astro component before using that to render a youtube link as a native player.
YouTubeEmbed.tsx
import React from 'react';
import YouTube, { YouTubeProps } from 'react-youtube';
export default function YouTubeEmbed({ id }: { id: string }) {
const onPlayerReady: YouTubeProps['onReady'] = (event) => {
// access to player in all event handlers via event.target
event.target.pauseVideo();
};
const opts: YouTubeProps['opts'] = {
height: '390',
width: '640',
playerVars: {
// https://developers.google.com/youtube/player_parameters
},
};
return <YouTube videoId={id} opts={opts} onReady={onPlayerReady} />;
}
ArticleYouTubeEmbed.astro
---
import YouTube from 'react-youtube';
import getYouTubeId from 'get-youtube-id';
import YouTubeEmbed from './YouTubeEmbed.tsx';
const { astroClass, node } = Astro.props;
const id = getYouTubeId(node.url);
---
<div class={`video-center ${astroClass}`}>
<YouTubeEmbed id={id} client:load />
</div>
This content is then routed through Sanity.io where I really just store the url, but also include it in their block content. Everything gets rendered out on my pages/[slug]
as part of that block content.
Everything works fine in development on my local machine but when I push it to Vercel, it gives me the error below during build.
Cloning completed: 416.825ms
Looking up build cache...
Build cache downloaded [40.92 MB]: 1981.419ms
Running "vercel build"
Vercel CLI 28.2.0
Installing dependencies...
added 4 packages in 1s
187 packages are looking for funding
run `npm fund` for details
Detected `package-lock.json` generated by npm 7+...
Running "npm run build"
> @example/[email protected] build
> astro build
08:53:50 PM [build] output target: static
08:53:50 PM [build] Collecting build info...
08:53:50 PM [build] Completed in 20ms.
08:53:50 PM [build] Building static entrypoints...
08:53:53 PM [build] Completed in 2.76s.
building client
Completed in 1.02s.
generating static routes
▶ src/pages/index.astro
└─ /index.html (+561ms)
▶ src/pages/article/index.astro
└─ /article/index.html (+2ms)
▶ src/pages/article/[slug].astro
error Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
Code:
71 | b.treeContext=ib(c,1,0);try{W(a,b,d)}finally{b.treeContext=c}}else W(a,b,d);return;case Sa:c=c.type;d=Hb(c,d);Ib(a,b,c,d,f);return;case Na:f=d.children;c=c._context;d=d.value;e=c._currentValue2;c._currentValue2=d;g=D;D=d={parent:g,depth:null===g?0:g.depth+1,context:c,parentValue:e,value:d};b.context=d;W(a,b,f);a=D;if(null===a)throw Error("Tried to pop a Context at the root of the app. This is a bug in React.");d=a.parentValue;a.context._currentValue2=d===Xa?a.context._defaultValue:d;a=D=a.parent;
> 72 | b.context=a;return;case Oa:d=d.children;d=d(c._currentValue2);W(a,b,d);return;case Ta:f=c._init;c=f(c._payload);d=Hb(c,d);Ib(a,b,c,d,void 0);return}throw Error("Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: "+((null==c?c:typeof c)+"."));}}
| ^
73 | function W(a,b,c){b.node=c;if("object"===typeof c&&null!==c){switch(c.$$typeof){case Ia:Ib(a,b,c.type,c.props,c.ref);return;case Ja:throw Error("Portals are not currently supported by the server renderer. Render them conditionally so that they only appear on the client render.");case Ta:var d=c._init;c=d(c._payload);W(a,b,c);return}if(ra(c)){Kb(a,b,c);return}null===c||"object"!==typeof c?d=null:(d=Ya&&c[Ya]||c["@@iterator"],d="function"===typeof d?d:null);if(d&&(d=d.call(c))){c=d.next();if(!c.done){var f=
74 | [];do f.push(c.value),c=d.next();while(!c.done);Kb(a,b,f)}return}a=Object.prototype.toString.call(c);throw Error("Objects are not valid as a React child (found: "+("[object Object]"===a?"object with keys {"+Object.keys(c).join(", ")+"}":a)+"). If you meant to render a collection of children, use an array instead.");}"string"===typeof c?(d=b.blockedSegment,d.lastPushedText=Ha(b.blockedSegment.chunks,c,a.responseState,d.lastPushedText)):"number"===typeof c&&(d=b.blockedSegment,d.lastPushedText=Ha(b.blockedSegment.chunks,
75 | ""+c,a.responseState,d.lastPushedText))}function Kb(a,b,c){for(var d=c.length,f=0;f<d;f++){var e=b.treeContext;b.treeContext=ib(e,d,f);try{Jb(a,b,c[f])}finally{b.treeContext=e}}}
Stacktrace:
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
at Ib (/vercel/path0/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.min.js:72:155)
at W (/vercel/path0/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.min.js:73:89)
at Ib (/vercel/path0/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.min.js:67:482)
at W (/vercel/path0/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.min.js:73:89)
at Eb (/vercel/path0/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.min.js:82:216)
at Vb (/vercel/path0/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.min.js:97:145)
at Object.exports.renderToString (/vercel/path0/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.min.js:100:108)
at Object.renderToStaticMarkup$1 (file:///vercel/path0/dist/entry.mjs?time=1662065634413:125:19)
at renderComponent (file:///vercel/path0/dist/entry.mjs?time=1662065634413:1035:66)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
Error! Command "npm run build" exited with 1
I've checked the other threads here regarding the error and:
.tsx
and the .astro
above as standalone components both through the Sanity setup and straight on the page. Everything works in development, nothing works in production.My tsconfig.json is just the standard from Astro docs:
{
"extends": "astro/tsconfigs/strict",
"include": ["**/*.ts", "**/*.tsx", "**/*.jsx"],
"exclude": ["node_modules", "studio"],
"compilerOptions": {
"types": ["astro/client"],
"target": "ESNext",
"module": "ESNext",
// Enable node-style module resolution, for things like npm package imports.
"moduleResolution": "node",
// Enable JSON imports.
"resolveJsonModule": true,
// Enable stricter transpilation for better output.
"isolatedModules": true,
// Astro will directly run your TypeScript code, no transpilation needed.
"noEmit": true,
"baseUrl": "/",
"paths": {
"@components/*": ["src/components/*"],
"@layouts/*": ["src/layouts/*"]
}
}
}
Can anyone think of why?
Upvotes: 0
Views: 4532
Reputation: 489
As specified in the Astro documentation:
With all client directives except client:only, your component will first render on the server to generate static HTML. Component JavaScript will be sent to the browser according to the directive you chose. The component will then hydrate and become interactive.
Try using client:only
directive to render component on client side only:
<div class={`video-center ${astroClass}`}>
<YouTubeEmbed id={id} client:load />
</div>
Upvotes: 0