Custom template and Content Security Policy
Nincha opened this issue · comments
Hi,
Thanks for the amazing work!
I'm using custom template like this, which is working fine on development environment:
Vue.use(VueBreadcrumbs, {
template:
' <nav v-if="$breadcrumbs.length" aria-label="breadcrumb" class="ncBreadcrumbs">\n' +
' <localized-link class="icon-home-outline" tag="a" to="/""></localized-link>\n' +
' <span v-for="(crumb, index, key) in $breadcrumbs" v-if="crumb.meta.breadcrumb" :key="key" class="breadcrumbItem" :class="[(index == $breadcrumbs.length - 1 ? \'breadcrumbCurrent\' : \'\')]" aria-current="page">\n' +
' <span class="icon-right-open-outline"></span>' +
' <localized-link v-if="index !== $breadcrumbs.length - 1" tag="a" to="{ path: getPath(crumb) }" class="breadcrumbText">{{ getBreadcrumb(crumb.meta.breadcrumbshort) }}</localized-link>' +
' <span v-if="index == $breadcrumbs.length - 1" class="breadcrumbText" v-html="$t( getBreadcrumb(crumb.meta.breadcrumb) )"></span>' +
' </span>\n' +
' </nav>'
});
It appears that the use of the custom template seems to require eval() or a similar method, and fails to load breadcrumbs into the page if 'unsafe-eval' isn't defined under script-src in the server's Content Security Policy headers.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src
Could you consider implementing custom template injection from a file template instead? Or maybe create a second implementation method, to allow old code compatibility ; that would allow the plugin to be compatible with secured server policies. :)
For the time being, I will keep it simple and inject a hard coded breadcrumb html on every page (as it's a small project, it's ok for that one but I will implement breadcrumbs in larger vue projects later in 2020, so that won't be possible on them
Cheers,
Charlie
@Nincha Hi, sorry for the long answer.
- Please note that I use a declarative approach to define the template.
- You can try using
string template
to define a template - maybe it is worth giving up
Runtime-only
to the sideRuntime + Compiler
Could this be solved with slots? Perhaps a default slot for the root element and then a repeated slot for the items within, providing the scoped data one would need to use an alternative set of components to render their breadcrumbs.
Sorry I didn't see your answer @Scrum, the last message notified me just now. Thanks for the feedback, I'll try to give a try to your suggestions in a near future. :)
Alternatively, I was able to use the custom templates with components by writing a render function instead of using the template string. Not ideal, but was able to get past it without a change in the library. I think slots would still be a nice touch for those that would still prefer to compose their template in a traditional single file component.
Here is what I wrote to use the this library with the breadcrumb components from boostrap-vue:
import Vue from "vue";
import VueBreadcrumbs from "vue-2-breadcrumbs";
Vue.use(VueBreadcrumbs, {
render: function(c) {
if (this.$breadcrumbs.length) {
return c( "b-breadcrumb", this.$breadcrumbs.map((crumb, index) => {
return crumb.meta.breadcrumb
? c(
"b-breadcrumb-item",
{
key: `breadcrumb-item-${index}`,
props: {
to: { path: this.getPath(crumb) }
}
},
this.getBreadcrumb(crumb.meta.breadcrumb)
)
: null;
})
);
}
}
});