diff --git a/deno.lock b/deno.lock index 476e8585fe7..b0c99ebecd8 100644 --- a/deno.lock +++ b/deno.lock @@ -1,6 +1,7 @@ { "version": "5", "specifiers": { + "jsr:@astral/astral@0.5.6": "0.5.6", "jsr:@astral/astral@~0.5.6": "0.5.6", "jsr:@deno-library/progress@^1.5.1": "1.5.1", "jsr:@deno/cache-dir@0.14": "0.14.0", @@ -6110,6 +6111,17 @@ "npm:vite@^7.1.4" ] } + }, + "links": { + "npm:@deno/vite-plugin@2.0.2": { + "dependencies": [ + "npm:@jsr/deno__loader@0.5", + "npm:@jsr/std__jsonc@1" + ], + "peerDependencies": [ + "npm:vite@5 || 6 || 7 || 8" + ] + } } } } diff --git a/docs/latest/advanced/vite.md b/docs/latest/advanced/vite.md index cbabf0ff43f..dec529eb355 100644 --- a/docs/latest/advanced/vite.md +++ b/docs/latest/advanced/vite.md @@ -83,7 +83,8 @@ Behind the scenes, the Fresh Vite plugin: During development (`deno task dev`), the Fresh Vite plugin enables HMR so that changes to components, islands, and CSS are reflected in the browser instantly without a full page reload. This is powered by Prefresh, Preact's fast refresh -implementation. +implementation. See [Styling](/docs/concepts/styling) for details on how CSS is +handled. ## Debugging diff --git a/docs/latest/concepts/file-routing.md b/docs/latest/concepts/file-routing.md index 8bd576cca3b..582cb40c6d5 100644 --- a/docs/latest/concepts/file-routing.md +++ b/docs/latest/concepts/file-routing.md @@ -101,6 +101,9 @@ array. This is a top-level export, separate from `config`: export const css = ["./assets/dashboard.css"]; ``` +See [Styling](/docs/concepts/styling) for all CSS approaches including CSS +Modules, preprocessors, and global stylesheets. + ## Route Groups When working with [layouts](/docs/advanced/layouts) or diff --git a/docs/latest/concepts/islands.md b/docs/latest/concepts/islands.md index b2f88a7efbc..a0fa1cf177a 100644 --- a/docs/latest/concepts/islands.md +++ b/docs/latest/concepts/islands.md @@ -118,12 +118,44 @@ import OtherIsland from "../islands/other-island.tsx"; ; ``` -## Rendering islands on client only +## Styling islands -When using client-only APIs, like `EventSource` or `navigator.getUserMedia`, the -component would error during server-side rendering. Use the `IS_BROWSER` -constant from `fresh/runtime` to guard browser-only code. It is `false` on the -server and `true` in the browser: +Islands can import CSS files just like any other module. CSS Modules +(`*.module.css`) are the recommended approach for scoped styles. Fresh +automatically collects CSS from each island's module graph and injects it as +`` tags during server rendering, so styles are available before hydration. + +See [Styling](/docs/concepts/styling) for details on CSS Modules, global +stylesheets, and other approaches. + +## Client-only islands + +Some libraries (e.g. Monaco Editor, certain charting libraries) reference +browser globals like `document` at the module top level, which crashes during +server-side rendering. You can mark an island as **client-only** by adding +`export const clientOnly = true`. Fresh will skip executing the component on the +server and render an empty placeholder instead. On the client, the component +renders normally. + +```tsx islands/my-editor.tsx +export const clientOnly = true; + +export default function MyEditor() { + // Safe to use document, window, etc. — this code never runs on the server. + return