Hi there,
I currently have a project using Stencil and the reactOutputTarget to create an icon component, similar to the way the Ionicons icon component works - loading in svg content at runtime from a static public/assets folder
I’m trying to import the generated React component in another project, which uses Next.js, but I’m finding that the getAssetPath()
call to retrieve icon content keeps returning the current page’s path - e.g. localhost:3000/section/page returns its assetPath
as /section/page
, and the component attempts to fetch localhost:3000/section/page/assets/icon.svg
, which is not going to work. It should be localhost:3000/assets/icon.svg
.
I didn’t hit this problem in any local testing or setting the components up in Storybook, presumably because all those were loaded from the web server root. I can’t for the life of me work out how to use setAssetPath()
- it’s not exported by any of my bundles (I’m not currently building dist-custom-elements-bundle
which is the only place it gets mentioned in the docs). I’m importing my components-react
package in the Next.js project, which exports only the component proxies as far as I can tell.
Where am I going wrong? How can I get assetPath
to return '/'
, or (ideally) be configurable to the app consuming the react components library, in case the app’s public path needs to be different from mine?
stencil.config.js (edited)
export const config: Config = {
namespace: 'my-components',
taskQueue: 'async',
outputTargets: [
reactOutputTarget({
componentCorePackage: 'my-components',
proxiesFile: '../components-react/src/components.ts',
includeDefineCustomElements: true,
}),
{
type: 'dist',
esmLoaderPath: '../loader',
},
{
type: 'docs-readme',
strict: true,
},
{
type: 'www',
serviceWorker: null, // disable service workers
},
],
plugins: [sass({})],
globalStyle: './src/global/variables.scss',
};
icon-utils.tsx (edited)
import { getAssetPath } from '@stencil/core';
const iconCache = {};
const requestCache = {};
export async function fetchIcon({ icon }): Promise<IconData> {
if (iconCache[icon]) {
return iconCache[icon];
}
if (!requestCache[icon]) {
requestCache[icon] = fetch(getAssetPath(`./assets/${icon}.json`))
.then((resp) => resp.json())
.catch(() => {
console.error(`"${icon}" is not a valid icon name`);
return {};
});
}
const iconData = await requestCache[icon];
iconCache[icon] = iconData;
return iconData;
}
page.js (edited)
import { MyIcon } from 'my-components-react'; // is there a better way to import? this seems to pull in the whole component bundle
render() {
return <MyIcon name="icon-name" />;
}
versions:
├─ @stencil/core@2.4.0
├─ @stencil/react-output-target@0.0.9
├─ @stencil/sass@1.4.1