Skip to content

Commit

Permalink
feat(core): islands
Browse files Browse the repository at this point in the history
<!--- Provide a general summary of your changes in the title above -->

## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [ ] Bug fix (a non-breaking change which fixes an issue)
- [x] New feature (a non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)

## Description
<!--- Describe your changes in detail -->
<!--- Why is this change required? What problem does it solve? -->
<!--- If it resolves an open issue, please link to the issue here. For example "Resolves: #137" -->

Closes #494

This PR introduces support for Nuxt Server Components (a.k.a Islands).

## Checklist:
<!--- Put an `x` in all the boxes that apply. -->
<!--- If your change requires a documentation PR, please link it appropriately -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [ ] I have added tests to cover my changes (if not applicable, please state why)
  • Loading branch information
vejja committed Jul 30, 2024
1 parent 765d7e1 commit 8ae7c5f
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 16 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@
"@types/node": "^18.18.1",
"eslint": "^8.50.0",
"nuxt": "^3.11.2",
"vitest": "^1.3.1",
"typescript": "^5.4.5"
"typescript": "^5.4.5",
"vitest": "^1.3.1"
},
"stackblitz": {
"installDependencies": false,
Expand Down
3 changes: 3 additions & 0 deletions playground/components/ServerComponent.server.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<div>Server component</div>
</template>
6 changes: 6 additions & 0 deletions playground/pages/island.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<template>
<div>
Island Page
<ServerComponent />
</div>
</template>
22 changes: 12 additions & 10 deletions src/runtime/nitro/plugins/50-updateCsp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@ import type { ContentSecurityPolicyValue } from '../../../types/headers'
*/
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('render:html', (response, { event }) => {
const rules = resolveSecurityRules(event)
if (rules.enabled && rules.headers) {
const headers = rules.headers

if (headers.contentSecurityPolicy) {
const csp = headers.contentSecurityPolicy
const nonce = event.context.security?.nonce
const scriptHashes = event.context.security?.hashes?.script
const styleHashes = event.context.security?.hashes?.style
headers.contentSecurityPolicy = updateCspVariables(csp, nonce, scriptHashes, styleHashes)
if (!response.island) {
const rules = resolveSecurityRules(event)
if (rules.enabled && rules.headers) {
const headers = rules.headers

if (headers.contentSecurityPolicy) {
const csp = headers.contentSecurityPolicy
const nonce = event.context.security?.nonce
const scriptHashes = event.context.security?.hashes?.script
const styleHashes = event.context.security?.hashes?.style
headers.contentSecurityPolicy = updateCspVariables(csp, nonce, scriptHashes, styleHashes)
}
}
}
})
Expand Down
10 changes: 6 additions & 4 deletions src/runtime/nitro/plugins/60-recombineHtml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ export default defineNitroPlugin((nitroApp) => {

// Let's insert the CSP meta tag just after the first tag which should be the charset meta
let insertIndex = 0
const metaCharsetMatch = html.head[0].match(/^<meta charset="(.*?)">/mdi)
if (metaCharsetMatch && metaCharsetMatch.indices) {
insertIndex = metaCharsetMatch.indices[0][1]
if (html.head.length > 0) {
const metaCharsetMatch = html.head[0].match(/^<meta charset="(.*?)">/mdi)
if (metaCharsetMatch && metaCharsetMatch.indices) {
insertIndex = metaCharsetMatch.indices[0][1]
}
html.head[0] = html.head[0].slice(0, insertIndex) + `<meta http-equiv="Content-Security-Policy" content="${headerValue}">` + html.head[0].slice(insertIndex)
}
html.head[0] = html.head[0].slice(0, insertIndex) + `<meta http-equiv="Content-Security-Policy" content="${headerValue}">` + html.head[0].slice(insertIndex)
}
})
})

0 comments on commit 8ae7c5f

Please sign in to comment.