Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an option for inline scripts in html to be externalised #1776

Open
abovethewater opened this issue Jun 29, 2021 · 5 comments
Open

Add an option for inline scripts in html to be externalised #1776

abovethewater opened this issue Jun 29, 2021 · 5 comments
Labels
feature / enhancement New feature or request
Milestone

Comments

@abovethewater
Copy link

I am trying to reuse a number of my svelte components in a Chrome extension that replaces the newtab page.

I am using a site generated with adapter-static, and the client side router disabled, but i still need javascript enabled for the likes of a search bar.

On a default build of a test page the Javascript does not work, and I see the following error in the extension console:

Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-mCb4RZPtIMMHYC2/zT6SdIhwTomYnh+ky3BLobKXNn0='), or a nonce ('nonce-...') is required to enable inline execution.

index.html:20 (anonymous function)

<script type="module">

Chrome is pushing the move to manifest v3, which has increased content security policies, one of which is to disallow the use of unsafe, hash, or nonce based exceptions in the content_security_policy.extension_pages (regardless of what the above error states, using any of those causes the extension to fail to be installed).

If however, I manually move the contents of that inline script into a file called init.js, and change the script to reference it:

<script type="module" src="/./app/init.js"></script>

then my extension works as expected.

The inline script appears to be hardcoded in render.js:

init = `<script type="module">
import { start } from ${s(options.entry.file)};
start({
target: ${options.target ? `document.querySelector(${s(options.target)})` : 'document.body'},
paths: ${s(options.paths)},
session: ${try_serialize($session, (error) => {
throw new Error(`Failed to serialize session data: ${error.message}`);
})},
host: ${page && page.host ? s(page.host) : 'location.host'},
route: ${!!page_config.router},
spa: ${!page_config.ssr},
trailing_slash: ${s(options.trailing_slash)},
hydrate: ${page_config.ssr && page_config.hydrate? `{
status: ${status},
error: ${serialize_error(error)},
nodes: [
${branch
.map(({ node }) => `import(${s(node.entry)})`)
.join(',\n\t\t\t\t\t\t')}
],
page: {
host: ${page.host ? s(page.host) : 'location.host'}, // TODO this is redundant
path: ${s(page.path)},
query: new URLSearchParams(${s(page.query.toString())}),
params: ${s(page.params)}
}
}` : 'null'}
});
</script>`;

Ideally, there'd be a manifest v3 friendly way of running the inline script (which I have failed to find, but maybe someone else has worked around).

Failing that I'm asking for the option for the init code to be referenced in an external script, e.g.

<script context="module">
	export const inline = false;
</script>

thanks.

@Palmik
Copy link

Palmik commented Jul 18, 2021

This is not an issue exclusive to extensions, it's important also for web sites (as using 'unsafe-inline' should be avoided).

@adam-kov
Copy link

Same problem here. The only inline script on my website is the one that Svelte uses to initialize the app. I'm also using SSR, so I can't even move the script to another file by hand. I can't think of a solution now, other than to add script-src 'unsafe-inline'; to my CSP header (which is not a solution at all).

@darrylyeo
Copy link

I would love to have this as well. It would be awesome to have a dedicated SvelteKit adapter for Chrome extensions.

@harvey-k
Copy link
Contributor

It seems like this would be addressed by #93

@Karlinator
Copy link
Contributor

Karlinator commented Sep 8, 2021

@abovethewater This is referenced in the linked issue, but you could do a workaround like this to move the script out of the head (since you're using adapter-static): https://twitter.com/Rich_Harris/status/1422594746825023492 It's kind of a grotesque hack but it probably will work.

Something like this seems like the most reasonable solution for building into adapter-static anyway.

Theo-Steiner added a commit to Theo-Steiner/sveltekit-adapter-browser-extension that referenced this issue Mar 5, 2022
The content security policy of manifest_version 3 does not allow for inlined scripts. Until kit implements a config option ( sveltejs/kit#1776 ) to externalize scripts, these changes should do for a quick and dirty externalization of the scripts' contents
@Rich-Harris Rich-Harris added this to the post-1.0 milestone Apr 26, 2022
antony pushed a commit to antony/sveltekit-adapter-browser-extension that referenced this issue Jun 16, 2022
* Adapt to adapter API changes introduced by #4192

* Modify readme to reflect newly required config boilerplate

* Make manifest_version 3 default with option to specify

* Document adapter-browser-extension options 

Document options that can be passed to the adapter, including the newly introduced option to pass a  manifestVersion.

* Modify CSP as only externalized scripts are allowed in MV3

* Introduce helper function to externalize script content

The content security policy of manifest_version 3 does not allow for inlined scripts. Until kit implements a config option ( sveltejs/kit#1776 ) to externalize scripts, these changes should do for a quick and dirty externalization of the scripts' contents
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature / enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

8 participants