diff --git a/app.config.ts b/app.config.ts index 946d99208..9f0e64261 100644 --- a/app.config.ts +++ b/app.config.ts @@ -51,7 +51,9 @@ function docsData() { const theme = defineTheme({ componentsPath: import.meta.resolve("./src/solidbase-theme"), + extends: defaultTheme, }); + export default defineConfig( createWithSolidBase(theme)( { @@ -87,6 +89,7 @@ export default defineConfig( cursorColor: "var(--twoslash-cursor)", }, }, + languageSwitcher: true, }, toc: { minDepth: 2, @@ -147,6 +150,7 @@ export default defineConfig( import { readFile } from "node:fs/promises"; import { codeToHtml } from "shiki"; +import defaultTheme from "@kobalte/solidbase/default-theme"; function heroCodeSnippet() { const virtualModuleId = "solid:hero-code-snippet"; diff --git a/src/routes/advanced-concepts/data.json b/old pages/advanced-concepts/data.json similarity index 100% rename from src/routes/advanced-concepts/data.json rename to old pages/advanced-concepts/data.json diff --git a/src/routes/advanced-concepts/fine-grained-reactivity.mdx b/old pages/advanced-concepts/fine-grained-reactivity.mdx similarity index 100% rename from src/routes/advanced-concepts/fine-grained-reactivity.mdx rename to old pages/advanced-concepts/fine-grained-reactivity.mdx diff --git a/src/routes/concepts/components/basics.mdx b/old pages/concepts/components/basics.mdx similarity index 100% rename from src/routes/concepts/components/basics.mdx rename to old pages/concepts/components/basics.mdx diff --git a/src/routes/concepts/components/class-style.mdx b/old pages/concepts/components/class-style.mdx similarity index 100% rename from src/routes/concepts/components/class-style.mdx rename to old pages/concepts/components/class-style.mdx diff --git a/src/routes/concepts/components/data.json b/old pages/concepts/components/data.json similarity index 100% rename from src/routes/concepts/components/data.json rename to old pages/concepts/components/data.json diff --git a/src/routes/concepts/components/event-handlers.mdx b/old pages/concepts/components/event-handlers.mdx similarity index 100% rename from src/routes/concepts/components/event-handlers.mdx rename to old pages/concepts/components/event-handlers.mdx diff --git a/src/routes/concepts/components/props.mdx b/old pages/concepts/components/props.mdx similarity index 100% rename from src/routes/concepts/components/props.mdx rename to old pages/concepts/components/props.mdx diff --git a/src/routes/concepts/context.mdx b/old pages/concepts/context.mdx similarity index 100% rename from src/routes/concepts/context.mdx rename to old pages/concepts/context.mdx diff --git a/src/routes/concepts/control-flow/conditional-rendering.mdx b/old pages/concepts/control-flow/conditional-rendering.mdx similarity index 100% rename from src/routes/concepts/control-flow/conditional-rendering.mdx rename to old pages/concepts/control-flow/conditional-rendering.mdx diff --git a/src/routes/concepts/control-flow/data.json b/old pages/concepts/control-flow/data.json similarity index 100% rename from src/routes/concepts/control-flow/data.json rename to old pages/concepts/control-flow/data.json diff --git a/src/routes/concepts/control-flow/dynamic.mdx b/old pages/concepts/control-flow/dynamic.mdx similarity index 100% rename from src/routes/concepts/control-flow/dynamic.mdx rename to old pages/concepts/control-flow/dynamic.mdx diff --git a/src/routes/concepts/control-flow/error-boundary.mdx b/old pages/concepts/control-flow/error-boundary.mdx similarity index 100% rename from src/routes/concepts/control-flow/error-boundary.mdx rename to old pages/concepts/control-flow/error-boundary.mdx diff --git a/src/routes/concepts/control-flow/list-rendering.mdx b/old pages/concepts/control-flow/list-rendering.mdx similarity index 100% rename from src/routes/concepts/control-flow/list-rendering.mdx rename to old pages/concepts/control-flow/list-rendering.mdx diff --git a/src/routes/concepts/control-flow/portal.mdx b/old pages/concepts/control-flow/portal.mdx similarity index 100% rename from src/routes/concepts/control-flow/portal.mdx rename to old pages/concepts/control-flow/portal.mdx diff --git a/src/routes/concepts/data.json b/old pages/concepts/data.json similarity index 100% rename from src/routes/concepts/data.json rename to old pages/concepts/data.json diff --git a/src/routes/concepts/derived-values/data.json b/old pages/concepts/derived-values/data.json similarity index 100% rename from src/routes/concepts/derived-values/data.json rename to old pages/concepts/derived-values/data.json diff --git a/src/routes/concepts/derived-values/derived-signals.mdx b/old pages/concepts/derived-values/derived-signals.mdx similarity index 100% rename from src/routes/concepts/derived-values/derived-signals.mdx rename to old pages/concepts/derived-values/derived-signals.mdx diff --git a/src/routes/concepts/derived-values/memos.mdx b/old pages/concepts/derived-values/memos.mdx similarity index 100% rename from src/routes/concepts/derived-values/memos.mdx rename to old pages/concepts/derived-values/memos.mdx diff --git a/src/routes/concepts/effects.mdx b/old pages/concepts/effects.mdx similarity index 100% rename from src/routes/concepts/effects.mdx rename to old pages/concepts/effects.mdx diff --git a/src/routes/concepts/intro-to-reactivity.mdx b/old pages/concepts/intro-to-reactivity.mdx similarity index 100% rename from src/routes/concepts/intro-to-reactivity.mdx rename to old pages/concepts/intro-to-reactivity.mdx diff --git a/src/routes/concepts/refs.mdx b/old pages/concepts/refs.mdx similarity index 100% rename from src/routes/concepts/refs.mdx rename to old pages/concepts/refs.mdx diff --git a/old pages/concepts/signals.mdx b/old pages/concepts/signals.mdx new file mode 100644 index 000000000..03a1b2492 --- /dev/null +++ b/old pages/concepts/signals.mdx @@ -0,0 +1,104 @@ +--- +title: Signals +order: 2 +use_cases: 'always, any solid project, state management, reactive data, core functionality' +tags: + - always + - state-management + - reactivity + - fundamentals + - core +version: '1.0' +--- + +Signals are the **core primitive for state** in Solid. +They provide a way to store a value, read it, and update it. +When a signal changes, anything that depends on it will update automatically. + +Signals can represent any kind of state in your application: +- simple values like numbers or strings +- complex values like objects or arrays +- application state such as the current user, theme, or page + +For an overview of how signals fit into Solid’s reactive model, see [Reactivity Basics](/reactivity/basics). + +## Creating a signal + +Use [`createSignal`](/reference/basic-reactivity/create-signal) from `solid-js` to create a signal. +It returns a pair of functions: +- a **getter** to read the value +- a **setter** to update the value + +```jsx +import { createSignal } from "solid-js"; + +const [count, setCount] = createSignal(0); +// ^ getter ^ setter +``` + +:::note +The syntax using `[` and `]` is called [array destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment). + +This lets you extract values from the array. +In the context of `createSignal`, the first value is the getter function, and the second value is the setter function. +::: + +## Accessing values + +The getter function returned by `createSignal` is used to access the value of the signal. +Call the getter function with no arguments to read the current value: + +```jsx +console.log(count()); // 0 +``` + +## Updating values + +The setter function returned by `createSignal` is used to update the value of the signal. +This function takes an argument that represents the new value of the signal: + +```jsx +setCount(count() + 1); + +console.log(count()); // 1 +``` + +The setter function can also take a function that passes the previous value. + +```jsx +setCount((prevCount) => prevCount + 1); + +console.log(count()); // 1 +``` + +## Reactivity + +Signals are **reactive**, which means that they automatically update when their value changes. +For example, using a signal inside JSX automatically makes the DOM update when the signal changes: + +```jsx +function Counter() { + const [count, setCount] = createSignal(0); + const increment = () => setCount((prev) => prev + 1); + + return ( +
+ Count: {count()} {/* Updates when `count` changes */} + +
+ ); +} +``` + +To learn how signals connect to effects and tracking scopes, see: +- [Reactive Side Effects](/reactivity/effects) +- [Memoized Computations](/reactivity/memo) + +## Related Pages + +- [Reactivity Basics](/reactivity/basics) +- [Reactive Side Effects](/reactivity/effects) +- [Memoized Computations](/reactivity/memo) +- [Introduction to Components](/components/intro) diff --git a/src/routes/concepts/stores.mdx b/old pages/concepts/stores.mdx similarity index 100% rename from src/routes/concepts/stores.mdx rename to old pages/concepts/stores.mdx diff --git a/src/routes/concepts/understanding-jsx.mdx b/old pages/concepts/understanding-jsx.mdx similarity index 96% rename from src/routes/concepts/understanding-jsx.mdx rename to old pages/concepts/understanding-jsx.mdx index 2b45b90b4..adec2dd04 100644 --- a/src/routes/concepts/understanding-jsx.mdx +++ b/old pages/concepts/understanding-jsx.mdx @@ -23,7 +23,7 @@ This provides a concise and readable way to create and represent components. Solid was designed to align closely with HTML standards. -```jsx +```tsx const element =

I'm JSX!!

``` @@ -31,7 +31,7 @@ It offers a distinct advantage, however: to copy/paste solutions from resources Solid sets itself apart by using JSX immediately as it returns [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction) elements. This lets you use dynamic expressions within your HTML by allowing variables and functions to be references with the use of curly braces (`{ }`): -```jsx +```tsx const Component = () => { const animal = { breed: "cat", name: "Midnight" } @@ -54,7 +54,7 @@ This updates only the necessary parts of the DOM when changes occur in the under Where HTML lets you have disconnected tags at the top level, JSX requires that a component to return a single root element. -:::advanced +:::note When working with JSX, parts of your code are translated into structured HTML that is placed at the start of the file. Static elements are processed differently from dynamic ones, which might change based on data or user actions. For dynamic elements, special markers are added for better handling during rendering. @@ -71,7 +71,7 @@ Self-closing tags are a must in JSX. Unlike in HTML, where elements like ``, ``, or `
` don't require explicit closure, JSX requires consistent self-closing tags. This helps to avoid potential rendering issues. -```jsx +```tsx ``` @@ -93,16 +93,17 @@ In JSX files, HTML attributes are used much like regular HTML, with a few key di (**Note:** When using ESLint, you will get a warning if you use lowercase.) - In cases where you can dynamically specify a value, you can replace the `"` and `"` with curly braces (`{ }`): -```jsx +```tsx ``` - :::note - If you wish to pass objects in JSX, such as with inline styling, you will have to use double curly braces (`{{ }}`). +:::note + +If you wish to pass objects in JSX, such as with inline styling, you will have to use double curly braces (`{{ }}`). -```jsx +```tsx - - ); -} -``` - -:::note -A tracking scope can be created by [`createEffect`](/reference/basic-reactivity/create-effect) or [`createMemo`](/reference/basic-reactivity/create-memo), which are other Solid primitives. - -Both functions subscribe to the signals accessed within them, establishing a dependency relationship. -Once this relationship is established, the function is notified whenever the signal changes. - -::: - -To learn more about how to use Signals in your application, visit our [state management guide](/guides/state-management). diff --git a/src/routes/control-flow/data.json b/src/routes/control-flow/data.json new file mode 100644 index 000000000..91d5713a5 --- /dev/null +++ b/src/routes/control-flow/data.json @@ -0,0 +1,4 @@ +{ + "title": "Control Flow", + "pages": [] +} diff --git a/src/routes/data.json b/src/routes/data.json index 5c04652ac..04e6f6004 100644 --- a/src/routes/data.json +++ b/src/routes/data.json @@ -2,10 +2,12 @@ "title": "root", "pages": [ "index.mdx", - "quick-start.mdx", - "concepts", - "advanced-concepts", - "guides", - "configuration" + "getting-started", + "reactivity", + "components", + "control-flow", + "rendering", + "advanced", + "guides" ] } diff --git a/src/routes/getting-started/data.json b/src/routes/getting-started/data.json new file mode 100644 index 000000000..5bf14a23a --- /dev/null +++ b/src/routes/getting-started/data.json @@ -0,0 +1,9 @@ +{ + "title": "Getting Started", + "pages": [ + "installation.mdx", + "quick-start.mdx", + "intro.mdx", + "understanding-jsx.mdx" + ] +} diff --git a/src/routes/getting-started/installation.mdx b/src/routes/getting-started/installation.mdx new file mode 100644 index 000000000..7af7852e6 --- /dev/null +++ b/src/routes/getting-started/installation.mdx @@ -0,0 +1,239 @@ +--- +title: Installation +order: 1 +--- + +Solid can be installed and configured manually in any JavaScript project using a package manager and build tool. +This approach provides full control over your project setup and configuration. + +To see how to get started quickly, check out the [Quick Start Guide](/getting-started/quick-start). + +## Manual Setup Guide + +### 1. Create Project Directory & initialize + +Create a new directory for your project and navigate into it: + +```sh +mkdir solid-project +cd solid-project +``` + +After creating and navigating into your project directory, you can initialize a new Git repository: + +```sh title="npm" tab="package-manager" +npm init -y +``` + +```sh title="pnpm" tab="package-manager" +pnpm init +``` + +```sh title="yarn" tab="package-manager" +yarn init -y +``` + +```sh title="bun" tab="package-manager" +bun init +``` + +### 2. Install Solid and Build Tools + +Install Solid as a dependency: + +```package-install +solid-js +``` + +In addition to Solid, you'll need a build tool. +Vite is the recommended build tool for Solid projects due to its speed and ease of use. Install Vite and the Solid plugin: + +```package-install-dev +vite vite-plugin-solid +``` + +### 3. Configure Vite + +To configure Vite for Solid, create a `vite.config.js` file in your project root: + +```js +import { defineConfig } from 'vite'; +import solid from 'vite-plugin-solid'; + +export default defineConfig({ + plugins: [solid()], + server: { + port: 3000, + }, + build: { + target: 'esnext', + }, +}); +``` + +### 4. Create HTML Template + +Create an `index.html` file in your project root: + +```html + + + + + + + Solid App + + + +
+ + + +``` + +### 5. Create Source Directory and Files + +Create the source directory and core application files: + +```sh +mkdir src +``` + +Once the `src` directory is created, you can create the following files: +- `src/index.jsx` - Application entry point +- `src/App.jsx` - Root component +- `src/index.css` - Global styles + +```jsx tab title="src/index.jsx" +/* @refresh reload */ +import { render } from 'solid-js/web'; +import App from './App'; +import './index.css'; + +const root = document.getElementById('root'); + +render(() => , root); +``` + +```jsx tab title="src/App.jsx" +import { createSignal } from 'solid-js'; + +function App() { + const [count, setCount] = createSignal(0); + + return ( +
+

Welcome to Solid

+
+ ); +} + +export default App; +``` + +```css tab title="src/index.css" +body { + margin: 0; + background-color: #f0f0f0; +} + +.app { + text-align: center; +} + +.app-header { + color: red; +} +``` + +### 6. Add Build Scripts + +Update your `package.json` to include the following scripts: +- `dev` - Start the development server +- `build` - Build the project for production +- `start` - Start the production server +- `serve` - Preview the production build + +```json +{ + //... + "scripts": { + "dev": "vite", + "build": "vite build", + "start": "vite", + "serve": "vite preview" + } + // ... +} +``` + +### 7. Start Development Server + +```package-run +dev +``` + +### 8. Open in Browser + +The development server will start on `http://localhost:3000`. Open this URL in your browser and begin developing your Solid application! + +## TypeScript Setup + +To add TypeScript support to your project: + +### 1. Install TypeScript Dependencies + +```package-install-dev +typescript +``` + +### 2. Create TypeScript Configuration + +Create a `tsconfig.json` file in your project root to configure TypeScript: + +```json +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "preserve", + "jsxImportSource": "solid-js", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} +``` + +### 3. Rename Files to TypeScript + +Rename your source files: +- `src/index.jsx` → `src/index.tsx` +- `src/App.jsx` → `src/App.tsx` + +In addition to updating the file extensions, ensure that your import statements reflect the new file types in the `index.html` file: + +```html title="index.html" + +``` + +## Next Steps + +With your development environment ready: + +1. **Explore the generated code** in `src/App.jsx` or `src/App.tsx` +2. **Modify components** and observe hot reloading in action +3. **Review the [Basic Concepts](/reactivity/basics)** to understand Solid's reactivity system +4. Learn to **build your first component** with the [Basics of Components](/components/basics) guide \ No newline at end of file diff --git a/src/routes/getting-started/intro.mdx b/src/routes/getting-started/intro.mdx new file mode 100644 index 000000000..bc90acac7 --- /dev/null +++ b/src/routes/getting-started/intro.mdx @@ -0,0 +1,62 @@ +--- +title: Introduction to Solid +order: 3 +--- + +Solid is a declarative JavaScript framework for building fast, reactive user interfaces. +With its fine-grained reactivity system and compilation-driven approach, Solid delivers exceptional performance while maintaining a developer-friendly experience similar to React. + +## What Makes Solid Different? + +Solid takes a unique approach to building web applications through **fine-grained reactivity**. Unlike frameworks that rely on a Virtual DOM, Solid compiles your components into optimized JavaScript that updates the real DOM directly—only changing what needs to change, when it needs to change. + +This means your applications are faster, more memory-efficient, and more responsive out of the box. + +## Core Principles + +- **Fine-Grained Reactivity**: Solid tracks dependencies at the most granular level, ensuring only affected parts of your UI update when data changes. +- **No Virtual DOM**: Direct DOM updates eliminate diffing overhead and improve performance. +- **Compilation-Based**: Components are compiled at build time into highly optimized JavaScript with minimal runtime overhead. +- **Familiar Syntax**: JSX-based components make Solid approachable for developers coming from React. +- **TypeScript First**: Built with TypeScript support from the ground up for a robust development experience. + +## Why Choose Solid? + +### Performance + +Solid consistently ranks at the top of JavaScript framework benchmarks. By eliminating the Virtual DOM and leveraging true reactivity, Solid achieves rendering speeds that rival vanilla JavaScript. + +### Developer Experience + +Write components using familiar JSX syntax while enjoying a simple, predictable API. Solid's reactivity primitives (`createSignal`, `createEffect`, `createMemo`) are intuitive and powerful, eliminating the need for complex state management libraries. + +### Small Bundle Size + +Solid's core is only a few kilobytes, making it ideal for performance-critical applications and mobile-first development. + +### Modern Features + +- Built-in support for Server-Side Rendering (SSR) +- Streaming and progressive hydration +- Strong TypeScript integration +- Flexible routing and state management +- Growing ecosystem of tools and libraries + +## Who Is Solid For? + +Solid is perfect for: +- Developers seeking maximum performance without sacrificing developer experience +- Teams building complex, interactive applications +- Projects where bundle size and runtime efficiency matter +- Developers familiar with React looking for a more performant alternative + +## Getting Started + +Ready to build with Solid? Here's where to go next: + +- [Quick Start Guide](/getting-started/quick-start) - Build your first Solid app +- [Understanding Reactivity](/concepts/reactivity) - Learn Solid's reactive primitives +- [Components Guide](/concepts/components) - Master Solid components +- [Tutorial](/tutorial/introduction) - Step-by-step interactive learning + +Welcome to Solid—let's build something fast! 🚀 diff --git a/src/routes/getting-started/quick-start.mdx b/src/routes/getting-started/quick-start.mdx new file mode 100644 index 000000000..68b685cc5 --- /dev/null +++ b/src/routes/getting-started/quick-start.mdx @@ -0,0 +1,69 @@ +--- +title: Quick Start +order: 2 +--- + +The fastest way to try Solid is to create a new project and run it locally. +In just a few minutes, you’ll have a working Solid app running in your browser. + +## Browser-Based Development + +To try Solid without a local setup: + +- **[Solid Playground](https://playground.solidjs.com/)** - Interactive online editor with live preview +- **StackBlitz Templates** - Full IDE experience in the browser: + - [JavaScript template](https://stackblitz.com/github/solidjs/templates/tree/master/js) + - [TypeScript template](https://stackblitz.com/github/solidjs/templates/tree/master/ts) + +## Using the Solid CLI + +The recommended approach uses the official Solid project generator: + +```package-create +solid +``` + +This command will prompt you to configure your project: + +- **Project Name**: Choose a name for your project directory +- **Type of Project**: You can select from the following options: + - `SolidStart` - Solid's full-stack framework for building web applications + - `SolidJS + Vite` - A minimal setup using Vite as the build tool + - `Library` - For creating a Solid-based library +- **TypeScript**: Choose whether to use TypeScript or JavaScript +- **Select a template**: Pick a starter template that fits your needs. To see a list of available templates, visit the [Solid Templates repository](https://github.com/solidjs/templates). + +Once the setup is complete, the CLI will create a new directory with your project files. Navigate to your project directory and install dependencies using your preferred package manager: + +```sh title="npm" tab="package-manager" +cd solid-project +npm install +``` + +```sh title="pnpm" tab="package-manager" +cd solid-project +pnpm install +``` + +```sh title="yarn" tab="package-manager" +cd solid-project +yarn install +``` + +```sh title="bun" tab="package-manager" +cd solid-project +bun install +``` + +```sh title="deno" tab="package-manager" +cd solid-project +deno install +``` + +After the dependencies are installed, start the development server: + +```package-run +dev +``` + +Once the server is running, you can open your browser and navigate to the provided local URL (typically `http://localhost:3000`) to see your Solid application in action! \ No newline at end of file diff --git a/src/routes/getting-started/understanding-jsx.mdx b/src/routes/getting-started/understanding-jsx.mdx new file mode 100644 index 000000000..16cfe1a93 --- /dev/null +++ b/src/routes/getting-started/understanding-jsx.mdx @@ -0,0 +1,152 @@ +--- +title: Understanding JSX +order: 4 +--- + +Solid's JSX is a JavaScript extension that lets you write **HTML-like syntax inside JavaScript**. +It keeps your rendering logic and markup together, making components easier to read and maintain. + +## How Solid uses JSX + +Solid was designed to align closely with HTML standards. + +```tsx +const element =

I'm JSX!!

+``` + +Unlike some other frameworks, Solid compiles JSX directly to real DOM nodes. +This means: + +- JSX expressions map closely to HTML. +- You can use variables and functions inline using curly braces `{}`. +- Only the parts of the DOM that depend on reactive state update. + +```tsx +const component = () => { + const animal = { breed: "cat", name: "Midnight" } + + return ( +

+ I have a {animal.breed} named {animal.name}. +

+ ) +} +``` + +## Solid's JSX Rules + +### Return a Single Root Element + +Each component must return a single root element. +Since JSX maintains the familiar tree-like structure of HTML, having a single root element helps keep the hierarchy clear. +If you need multiple top-level elements, wrap them in a `
`, `
`, or use a fragment `<>...`. + +```tsx +function App() { + return ( +
+

Hello World!

+

Welcome to JSX in Solid.

+
+ ) +} +``` + +:::note +JSX in Solid compiles into structured HTML. +Static elements are optimized once, while dynamic ones get special markers so Solid can update them efficiently. +Requiring a single root element keeps the hierarchy consistent and easier to update. +::: + +### Close All Tags + +All tags must be properly closed. +This includes self-closing tags like ``, ``, and `
`. + +```tsx +// Correct +Description + +// Incorrect +Description +``` + +### Properties vs Attributes + +In Solid's JSX, you can use both HTML attributes and JSX properties (props) to define element behavior and appearance. + +#### HTML attributes + +Solid's JSX blends HTML attributes with JavaScript expressions. + +- **HTML attributes** → work similar to regular HTML, but you can use JavaScript expressions inside curly braces `{}`. +- **Event listeners** → Solid's JSX allows you to add event listeners using camelCase (e.g., `onClick`, `onChange`) or all lowercase (e.g., `onclick`, `onchange`). +- **Inline styles** → You can apply styles directly using the `style` attribute with a JavaScript object. + +```tsx + + + +``` + +You can also use JavaScript expressions to set attribute values dynamically: + +```tsx +const isActive = true; + + +``` + +For more information on: + +- [Using Event Listeners](/components/how-to/event-listeners) +- [Styling Components](/components/how-to/styling) + +#### JSX Properties (Props) + +JSX properties (or props) are how you pass data and event handlers to components in Solid. +They work similarly to HTML attributes but can accept JavaScript expressions. + +In this example, the `name` prop is passed to the `Greeting` component, which uses it within its JSX: + +```tsx +function App() { + return ( +
+ + +
+ ); +} + +function Greeting(props) { + return

Hello, {props.name}!

; +} +``` + +The core concepts of JSX properties in Solid include: + +- **Static props:** Directly integrated into the HTML by cloning the template and using them as attributes. +- **Dynamic props:** Rely on state, allowing content or properties to change in response to user interactions or other events. +An example is changing the style of an element based on a signal (`value={value()}`). +- **Data transfer:** Props can be used to fill components with data from resources, such as API responses or context providers. + +This allows for components to update reactively when the underlying data changes. + +:::note +In JSX, expressions are applied in the order they appear. +This works for most elements, but some (i.e. ``) require attributes in a specific order. +When order matters, make sure to define expressions in the sequence the element expects. +::: + +## Related Pages + +- [Using Event Listeners](/components/how-to/event-listeners) +- [Styling Components](/components/how-to/styling) +- [Passing Data with Props](/components/props) diff --git a/src/routes/guides/data.json b/src/routes/guides/data.json index 364f3f925..88ddc06cb 100644 --- a/src/routes/guides/data.json +++ b/src/routes/guides/data.json @@ -1,14 +1,4 @@ { "title": "Guides", - "pages": [ - "styling-your-components.mdx", - "styling-components", - "state-management.mdx", - "routing-and-navigation.mdx", - "complex-state-management.mdx", - "fetching-data.mdx", - "testing.mdx", - "deploying-your-app.mdx", - "deployment-options" - ] + "pages": [] } diff --git a/src/routes/index.mdx b/src/routes/index.mdx index 54c333c0d..0056bb323 100644 --- a/src/routes/index.mdx +++ b/src/routes/index.mdx @@ -13,6 +13,8 @@ tags: version: '1.0' --- +[TODO: Convert to landing page. Move any relevant info into Solid Info] + # Overview Solid is a modern JavaScript framework designed to build responsive and high-performing user interfaces (UI). diff --git a/src/routes/pt-br/index.mdx b/src/routes/pt-br/index.mdx deleted file mode 100644 index 5cac3f8b6..000000000 --- a/src/routes/pt-br/index.mdx +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: Sumário -mainNavExclude: true -use_cases: >- - learning solid fundamentals, getting started, understanding reactivity, - framework introduction -tags: - - introduction - - fundamentals - - reactivity - - overview - - getting-started -version: '1.0' ---- - -# Sumário - -Solid is a modern JavaScript framework designed to build responsive and high-performing user interfaces (UI). -It prioritizes a simple and predictable development experience, making it a great choice for developers of all skill levels. - -## What is Solid? - -As a JavaScript framework, Solid embraces reactivity and fine-grained updates. - -Reactivity, in programming, refers to an applications' ability to respond to changes in data or user interactions. - -Traditionally, when a change occurs, the entire web page would need to reload to display the updated information. -In contrast, when using a fine-grained reactive system, updates are only applied to the parts of the page that need to be updated. - -Solid adopts the concept of fine-grained reactivity, updating only when the data the application depends on changes. -This decreases work and can result in faster load times and a smoother user experience overall. - -## Advantages of using Solid - -- **Performant**: Fine-grained reactivity allows Solid to update only what has changed, resulting in faster load times and smoother performance overall. - -- **Powerful**: Using less memory and processing power, Solid is capable of creating complex applications without compromising on functionality. - This also gives developers the flexibility over how and when updates happen. - -- **Pragmatic**: Rather than sticking to rigid structures or methods, Solid provides the freedom to choose the strategies and practices that work best for you. - -- **Productive**: Regardless of experience level, Solid's clear and predictable API makes developers' work simpler and more efficient. - -Solid aims to strike a balance between speed, efficiency, power, and flexibility, all while providing a developer-friendly environment. -This combination of features makes it a great choice to build responsive and high-performing UIs. - -## Quick links - -
- - Learn the basics of Solid through this interactive tutorial. - - - Start your first project with a template that fits your needs. - - - Explore the Solid ecosystem and find useful tools and libraries. - - - Help improve Solid by contributing to the documentation. - -
- -_Find our API documentation under the **Reference** tab_ - -Join the [Solid community on Discord](https://discord.com/invite/solidjs) to share your projects or get help from our community! - - - diff --git a/src/routes/pt-br/quick-start.mdx b/src/routes/pt-br/quick-start.mdx deleted file mode 100644 index 712bb43ca..000000000 --- a/src/routes/pt-br/quick-start.mdx +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: Começo rápido -use_cases: 'starting new projects, project setup, development environment, prototyping' -tags: - - quickstart - - setup - - templates - - playground - - new-project -version: '1.0' ---- - -## Solid playgrounds - -Experimente Solid in your browser by visiting our [interactive playground](https://playground.solidjs.com/). - -Additionally, we offer a [JavaScript](https://stackblitz.com/github/solidjs/templates/tree/master/js) and [TypeScript](https://stackblitz.com/github/solidjs/templates/tree/master/ts) Stackblitz starters, which provide a web-based development environment to get you started. - -## Creating a Solid application - -:::note[Prerequisites] - - - Familiarity with the command line - - Install [Node.js](https://nodejs.org/en) - -::: - -Solid offers convenient project templates that can help kickstart your development. -To get an application running, follow the steps below based on the language you prefer to use. - -### For JavaScript projects - -1. Run the following command in your terminal to get the JavaScript starter template: - -```bash frame="none" -npx degit solidjs/templates/js my-app -``` - -2. Navigate to your application's directory: - -```bash frame="none" -cd my-app -``` - -3. Install the necessary dependencies: - -```package-install-local -``` - -4. Run the application: - -```bash frame="none" -npm run dev -``` - -This will start the development server. -Now, you can open your browser and navigate to `localhost:3000` to see your application running. - -### For TypeScript projects - -1. To use a TypeScript template, run the following command in your terminal: - -```bash frame="none" -npx degit solidjs/templates/ts my-app -``` - -2. Navigate to your application's directory: - -```bash frame="none" -cd my-app -``` - -3. Install the necessary dependencies: - -```package-install-local -``` - -4. Run the application: - -```bash frame="none" -npm run dev -``` - -This will start the development server. -Now, you can open your browser and navigate to `localhost:3000` to see your application running. - -### Explore more templates - -Solid offers a variety of Vite templates to streamline your development process. -These resources are available on [GitHub](https://github.com/solidjs/templates). diff --git a/src/routes/pt-br/solid-router/index.mdx b/src/routes/pt-br/solid-router/index.mdx deleted file mode 100644 index 699e96308..000000000 --- a/src/routes/pt-br/solid-router/index.mdx +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: Sumário -mainNavExclude: true -use_cases: >- - learning solid fundamentals, getting started, understanding reactivity, - framework introduction -tags: - - introduction - - fundamentals - - reactivity - - overview - - getting-started -version: '1.0' ---- - -# Roteador - -Solid is a modern JavaScript framework designed to build responsive and high-performing user interfaces (UI). -It prioritizes a simple and predictable development experience, making it a great choice for developers of all skill levels. - -## What is Solid? - -As a JavaScript framework, Solid embraces reactivity and fine-grained updates. - -Reactivity, in programming, refers to an applications' ability to respond to changes in data or user interactions. - -Traditionally, when a change occurs, the entire web page would need to reload to display the updated information. -In contrast, when using a fine-grained reactive system, updates are only applied to the parts of the page that need to be updated. - -Solid adopts the concept of fine-grained reactivity, updating only when the data the application depends on changes. -This decreases work and can result in faster load times and a smoother user experience overall. - -## Advantages of using Solid - -- **Performant**: Fine-grained reactivity allows Solid to update only what has changed, resulting in faster load times and smoother performance overall. - -- **Powerful**: Using less memory and processing power, Solid is capable of creating complex applications without compromising on functionality. - This also gives developers the flexibility over how and when updates happen. - -- **Pragmatic**: Rather than sticking to rigid structures or methods, Solid provides the freedom to choose the strategies and practices that work best for you. - -- **Productive**: Regardless of experience level, Solid's clear and predictable API makes developers' work simpler and more efficient. - -Solid aims to strike a balance between speed, efficiency, power, and flexibility, all while providing a developer-friendly environment. -This combination of features makes it a great choice to build responsive and high-performing UIs. - -## Quick links - -
- - Learn the basics of Solid through this interactive tutorial. - - - Start your first project with a template that fits your needs. - - - Explore the Solid ecosystem and find useful tools and libraries. - - - Help improve Solid by contributing to the documentation. - -
- -_Find our API documentation under the **Reference** tab_ - -Join the [Solid community on Discord](https://discord.com/invite/solidjs) to share your projects or get help from our community! - - - diff --git a/src/routes/pt-br/solid-router/quick-start.mdx b/src/routes/pt-br/solid-router/quick-start.mdx deleted file mode 100644 index 712bb43ca..000000000 --- a/src/routes/pt-br/solid-router/quick-start.mdx +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: Começo rápido -use_cases: 'starting new projects, project setup, development environment, prototyping' -tags: - - quickstart - - setup - - templates - - playground - - new-project -version: '1.0' ---- - -## Solid playgrounds - -Experimente Solid in your browser by visiting our [interactive playground](https://playground.solidjs.com/). - -Additionally, we offer a [JavaScript](https://stackblitz.com/github/solidjs/templates/tree/master/js) and [TypeScript](https://stackblitz.com/github/solidjs/templates/tree/master/ts) Stackblitz starters, which provide a web-based development environment to get you started. - -## Creating a Solid application - -:::note[Prerequisites] - - - Familiarity with the command line - - Install [Node.js](https://nodejs.org/en) - -::: - -Solid offers convenient project templates that can help kickstart your development. -To get an application running, follow the steps below based on the language you prefer to use. - -### For JavaScript projects - -1. Run the following command in your terminal to get the JavaScript starter template: - -```bash frame="none" -npx degit solidjs/templates/js my-app -``` - -2. Navigate to your application's directory: - -```bash frame="none" -cd my-app -``` - -3. Install the necessary dependencies: - -```package-install-local -``` - -4. Run the application: - -```bash frame="none" -npm run dev -``` - -This will start the development server. -Now, you can open your browser and navigate to `localhost:3000` to see your application running. - -### For TypeScript projects - -1. To use a TypeScript template, run the following command in your terminal: - -```bash frame="none" -npx degit solidjs/templates/ts my-app -``` - -2. Navigate to your application's directory: - -```bash frame="none" -cd my-app -``` - -3. Install the necessary dependencies: - -```package-install-local -``` - -4. Run the application: - -```bash frame="none" -npm run dev -``` - -This will start the development server. -Now, you can open your browser and navigate to `localhost:3000` to see your application running. - -### Explore more templates - -Solid offers a variety of Vite templates to streamline your development process. -These resources are available on [GitHub](https://github.com/solidjs/templates). diff --git a/src/routes/reactivity/basics.mdx b/src/routes/reactivity/basics.mdx new file mode 100644 index 000000000..073d5e4eb --- /dev/null +++ b/src/routes/reactivity/basics.mdx @@ -0,0 +1,93 @@ +--- +title: "Reactivity Basics" +order: 1 +--- + + +Reactivity is the foundation of Solid. +It’s the programming model where **changes in data automatically update the parts of your app that depend on it**. + +Solid’s approach is **fine-grained**: only the exact parts of the DOM that depend on a value update. +This makes applications efficient and responsive, even as they grow. + +## Core principles of reactivity + +Solid’s reactivity is built on three key ideas: **signals, subscribers, and tracking scopes**. +Together, these create a system where updates are precise, automatic, and efficient. + +### Signals + +A **signal** is a reactive value container. +They consist of 2 parts: + +- **Getter** → reads the current value. +- **Setter** → updates the value and notifies dependents. + +```tsx +const [count, setCount] = createSignal(0); + +console.log(count()); // 0 +setCount(1); +console.log(count()); // 1 +``` + +Signals can hold any type of value: + +- Primitives (string, number, boolean). +- Objects and arrays. + +Learn more in the [Signals page](/reactivity/signals). + +### Subscribers + +If signals are the **source of truth**, subscribers are the **reactive consumers**. + +A subscriber is any function or construct that reads a signal inside a tracking scope and automatically re-runs whenever it changes. +This is what makes Solid’s reactivity *fine-grained*: only the subscribers that depend on a signal update. + +How subscribers work: + +1. **Observation** → subscriber runs and reads signals. +2. **Dependency tracking** → those signals register the subscriber. +3. **Response** → when a signal changes, the subscriber re-runs. + +### Tracking Scopes + +A **tracking scope** is the environment where Solid records which signals are being used. +When a signal is read within a tracking scope, it registers the current subscriber as a dependency. +Once that signal changes, it will notify the subscriber to re-run and update accordingly. + +Tracking scopes within Solid include: + +- Component render functions (JSX return values). +- Reactive computations (e.g., `createMemo`). +- Effects (e.g., `createEffect`) + +Example of a tracking vs non-tracking scope: + +```tsx +import { createSignal } from "solid-js"; + +function Counter() { + const [count, setCount] = createSignal(0); + + console.log(count()) // ❌ Not tracked — runs once + + return ( +
+

Count: {count()}

{/* ✅ tracked automatically - re-runs on update */} + +
+ ); +} +``` + +Tracking scopes are what enable **precise DOM updates**: only parts of the UI that depend on signals re-run. +You can learn more about [component lifecycles in the Intro to Components page](/components/intro). + + +## Related pages + +- [Signals](/reactivity/signals) - Understanding and using signals. +- [Effects](/reactivity/effects) - Managing side effects in your app. +- [Introduction to Components](/components/intro) - Building reusable UI components. diff --git a/src/routes/reactivity/data.json b/src/routes/reactivity/data.json new file mode 100644 index 000000000..7eacc5dcb --- /dev/null +++ b/src/routes/reactivity/data.json @@ -0,0 +1,12 @@ +{ + "title": "Reactivity", + "pages": [ + "basics.mdx", + "signals.mdx", + "derived-state.mdx", + "effects.mdx", + "stores.mdx", + "resources.mdx", + "how-to" + ] +} diff --git a/src/routes/reactivity/derived-state.mdx b/src/routes/reactivity/derived-state.mdx new file mode 100644 index 000000000..106ce7bdc --- /dev/null +++ b/src/routes/reactivity/derived-state.mdx @@ -0,0 +1,65 @@ +--- +title: "Derived State" +order: 3 +--- + +Derived state often refers to values that are computed based on other reactive values. +Rather than storing multiple pieces of state and manually keeping them consistent, Solid encourages you to derive new values from existing signals, memos, or stores. + +The benefits of derived state: +- You store only the minimal amount of state necessary. +- Relationships between values are described declaratively, making it easier to understand how data flows through your application. +- Derived values are automatically kept in sync with their dependencies. + +## Derived signals + +The simplest way to create derived state is by using a function that accesses one or more signals. + +```tsx +const [count, setCount] = createSignal(0); + +// A derived signal: always reflects count * 2 +const double = () => count() * 2; + +console.log(double()); // 0 +setCount(5); +console.log(double()); // 10 +``` + +In the above example, `double` is a derived signal that computes its value based on the `count` signal. +Whenever `count` changes, calling `double()` produces the correct and current value. +Any component or effect that uses `double()`, too, will update automatically when `count` changes. + +### Limitations of derived signals + +While derived signals are simple and effective for many use cases, they have some limitations: + +- **They do not cache their results.** + For derived signal call, the function is re-executed every time it is accessed, even if the underlying signals have not changed. + For trivial computations, this is not a problem, but for expensive calculations (eg. processing large datasets), this can lead to performance issues. +- **They do not create their own reactive scope.** + A derived function runs only when you call it. + Reactivity comes from the signals it touches, but there is no intermediate node in the reactivity graph. +- **Dependent computations can cause unnecessary updates.** + If a derived signal is used within another derived signal or effect, any change to its dependencies will trigger the entire chain to re-evaluate, even if the final value does not change. + +In other words, derived signals are best suited for lightweight computations, but they may not be ideal for more complex or performance-sensitive scenarios. + +## Memoizing derived state + +Memos are a specialized type of derived state that address the limitations of simple derived signals. +They cache results and only re-compute when their dependencies change, making them much more efficient for expensive or frequently accessed calculations. + +```tsx +// add example +``` + + +### Advantages of memos + +Memos offer several advantages over simple derived signals: + +- **Efficient execution** – a memo runs only once per dependency change, rather than re-executing every time it’s accessed. +- **Cached results** – results are stored and reused, avoiding unnecessary recomputation of expensive logic. +- **Change detection** – if dependencies change but the computed value is strictly equal (`===`) to the previous result, no downstream updates are triggered. +- **Automatic tracking** – any signal or memo read inside a memo’s function is automatically tracked, so the memo re-evaluates only when those dependencies change. \ No newline at end of file diff --git a/src/routes/reactivity/effects.mdx b/src/routes/reactivity/effects.mdx new file mode 100644 index 000000000..17936e4d9 --- /dev/null +++ b/src/routes/reactivity/effects.mdx @@ -0,0 +1,165 @@ +--- +title: "Effects" +order: 4 +--- + +Effects are reactive functions that run when the values they depend on change. +They’re the main way to manage side effects that occur outside an application's scope, such as: +- DOM manipulation +- Data fetching +- Subscriptions + +## What are Effects? + +An effect is a reactive function that **runs automatically whenever the values it depends on change**. + +Unlike [signals](/basics/signals) (which store state) or [memos](/basics/derived-state) (which derive state), effects connect your reactive data to the outside world. +They are used for running code that has side effects, meaning it interacts with or modifies something beyond Solid's reactive graph, such as: + +- updating or interacting with the DOM +- logging values +- fetching or subscribing to external data +- setting up or cleaning up resources + +Effects run **once when created** to establish its subscriptions, then **again whenever its dependencies change**. + +## Creating an Effect + +You create an effect using the `createEffect` function. +It takes a **callback function** as its first argument, which contains the code you want to run reactively. + +```tsx +import { createSignal, createEffect } from "solid-js"; + +function Counter() { + const [count, setCount] = createSignal(0); + + createEffect(() => { + console.log(`Count is: ${count()}`); + }); + + return ( + + ); +} +``` + +In this example, the effect logs the current value of `count` to the console. +The effect runs once when created, logging `Count is: 0`, and will run again whenever `count` changes, in this case when the button is clicked. + +## Lifecycle of an Effect + +An effect goes through a predictable cycle every time it's created and re-runs: + +### 1. **Initialization** + +When you call `createEffect`, the effect is immediately scheduled to run **once**. +This first run happens **after the current render phase** finishes, or after the component function returns its JSX. +This ensures that the DOM is already created and refs are assigned, allowing you to safely interact with the DOM. + +```tsx +createEffect(() => console.log("Initial run")); +console.log("Hello"); + +// Output: +// Hello +// Initial run +``` + +### 2. **Dependency tracking** + +During its first run, the effect records every reactive value it accesses (such as signals or memos). +It becomes subscribed to those values, which are now its **dependencies**. +From then on, the effect automatically re‑runs whenever any of its dependencies change. + +```tsx +const [count, setCount] = createSignal(0); + +createEffect(() => { + console.log(`Count: ${count()}`); +}); + +// Count: 0 runs immediately +// every setCount(...) re‑runs the effect +``` + +### 3. **Reactive Updates** + +Whenever *any* dependency changes, the effects is scheduled to run again. +This happens **after the current synchronous code completes**, ensuring that all changes are batched together. +This means that if the dependencies change multiple times in quick succession, the effect will only run *once* after all changes are made: + +```tsx +const [count, setCount] = createSignal(0); +const [name, setName] = createSignal("Solid"); + +createEffect(() => { + console.log(`Count: ${count()}, Name: ${name()}`); +}); + +setCount(1); +setName("SolidJS"); +``` + +In this example, the effect will only log `Count: 1, Name: SolidJS` once, after all changes have been made. + +### Lifecycle functions + +Effects are reactive and run whenever their dependencies change, but sometimes finer control is needed. +Solid provides lifecycle functions to manage when code runs and how it gets cleaned up. + +These functions are especially useful for: +- Running a side effect **only once** when the component mounts +- Cleaning up resources, event listeners, or other side effects when the component unmounts + +#### `onMount` + +The [`onMount`](TODO) function allows you to run code **once** when the component is first added to the DOM. +Unlike effects, `onMount` does **not track dependencies**. +It will execute the callback once, and never again. + +```tsx +import { onMount, createSignal, createEffect } from "solid-js"; + +function Component() { + const [data, setData] = createSignal(null); + + createEffect(() => { + // Still runs reactively whenever `data` changes + console.log("Data:", data()); + }); + + onMount(async () => { + // Runs only once when the component is mounted + const res = await fetch("/api/data"); + setData(await res.json()); + }); + + return
...
; +} +``` + +#### `onCleanup` + +Use [`onCleanup`](TODO) to **dispose of resources** before a component unmounts, or before an effect re-runs. +This will prevent memory leaks and ensure that any subscriptions or event listeners are properly removed. + +```tsx +import { createSignal, onCleanup } from "solid-js"; + +function App() { + const [count, setCount] = createSignal(0); + + const timer = setInterval(() => setCount(c => c + 1), 1000); + + onCleanup(() => { + // Runs when the component unmounts + clearInterval(timer); + }); + + return
Count: {count()}
; +} +``` + diff --git a/src/routes/reactivity/how-to/async-data.mdx b/src/routes/reactivity/how-to/async-data.mdx new file mode 100644 index 000000000..f8ba4a246 --- /dev/null +++ b/src/routes/reactivity/how-to/async-data.mdx @@ -0,0 +1,8 @@ +--- +title: "Async Data" +order: 2 +--- + +[TODO: +How to work with async Data +] \ No newline at end of file diff --git a/src/routes/reactivity/how-to/data.json b/src/routes/reactivity/how-to/data.json new file mode 100644 index 000000000..53d08c540 --- /dev/null +++ b/src/routes/reactivity/how-to/data.json @@ -0,0 +1,4 @@ +{ + "title": "How To", + "pages": ["derived-signals.mdx", "async-data.mdx", "debug-reactivity.mdx"] +} diff --git a/src/routes/reactivity/how-to/debug-reactivity.mdx b/src/routes/reactivity/how-to/debug-reactivity.mdx new file mode 100644 index 000000000..28ad0f70b --- /dev/null +++ b/src/routes/reactivity/how-to/debug-reactivity.mdx @@ -0,0 +1,4 @@ +--- +title: "Debugging Reactivity" +order: 3 +--- diff --git a/src/routes/reactivity/how-to/derived-signals.mdx b/src/routes/reactivity/how-to/derived-signals.mdx new file mode 100644 index 000000000..59dd72745 --- /dev/null +++ b/src/routes/reactivity/how-to/derived-signals.mdx @@ -0,0 +1,11 @@ +--- +title: "Derived Signals" +order: 1 +--- + +[TODO: +How to create derived signals +- when to use +- how to use +- examples +] \ No newline at end of file diff --git a/src/routes/reactivity/memos.mdx b/src/routes/reactivity/memos.mdx new file mode 100644 index 000000000..bdaf190ab --- /dev/null +++ b/src/routes/reactivity/memos.mdx @@ -0,0 +1,11 @@ +--- +title: "Memos" +order: 3 +--- + +[TODO: +Concept page on Memos +- Improve on existing page +- Move relevant sections to reference and vice versa +- Link out to how-to for derived signals where appropriate +] \ No newline at end of file diff --git a/src/routes/reactivity/overview.mdx b/src/routes/reactivity/overview.mdx new file mode 100644 index 000000000..f6351bcd0 --- /dev/null +++ b/src/routes/reactivity/overview.mdx @@ -0,0 +1,69 @@ +--- +title: "Overview" +order: 1 +--- + +[TODO: Review] + +:::note +While this guide can be helpful for understanding reactive systems, it does use some Solid-specific terminology and concepts. +::: + +Reactivity is what powers the interactivity of Solid apps. +This programming paradigm refers to a system's ability to respond to changes in data, or state, automatically and efficiently. +Solid is built with reactivity at the core of its design, assisting applications with staying up-to-date with its underlying data. + +## The Importance of Reactivity + +Reactivity is what keeps the user interface (UI) in sync with the underlying application state. +When the state changes, the UI is automatically updated, reducing the need for manual updates. + +In addition, reactivity enables real-time updates, allowing applications to reflect changes instantly without requiring a full page refresh. +This helps with creating more responsive and interactive user experiences. + +As an example, when building a Counter, you can use the reactive primitives provided by Solid to create a counter. +Once the counter is set up, whenever the count changes, the UI will automatically update to reflect the new count: + +```tsx +function Counter() { + const [count, setCount] = createSignal(0); + const increment = () => setCount((prev) => prev + 1); + + return ( +
+ Count: {count()}{" "} + {/* Only `count()` is updated when the button is clicked. */} + +
+ ); +} +``` + +## Reactive Principles + +### Signals + +Signals serve as the core elements within a reactive system. +They play a crucial role in tracking and managing state changes, allowing the UI to respond automatically when the underlying data changes. +They are responsible for storing and managing data, as well as triggering updates across the system. + +Signals are able to achieve this reactivity through the use of: + +- **Getters**: A function responsible for retrieving the current value of a signal. +When called within a reactive context, it will give access to the current value of the signal. +- **Setters**: This function is responsible for updating the value of a signal. +To trigger reactivity, setters notify the system that the signal's value has changed, prompting anything that depends on the signal to re-evaluate and update accordingly. + +### Subscribers + +Subscribers refer to other reactive contexts or components that depend on the value of a signal. +These automated responders keep the system up-to-date by re-evaluating and updating whenever the signal's value changes. + +Subscribers work based on two main actions: +- **Observation**: The core function of a subscriber is to observe signals. +This keeps the subscriber informed about any changes to the signal(s) they're tracking. +- **Respond**: Once the signal has updated and the subscriber is notified, it triggers a re-evaluation of the dependent computations or UI updates. + +[TODO: Some kind of image / code block??] \ No newline at end of file diff --git a/src/routes/reactivity/resources.mdx b/src/routes/reactivity/resources.mdx new file mode 100644 index 000000000..16342dad1 --- /dev/null +++ b/src/routes/reactivity/resources.mdx @@ -0,0 +1,8 @@ +--- +title: "Handling Async Data" +order: 6 +--- + +[TODO: +Concept page on Resource +] \ No newline at end of file diff --git a/src/routes/reactivity/signals.mdx b/src/routes/reactivity/signals.mdx new file mode 100644 index 000000000..e19c1e3c3 --- /dev/null +++ b/src/routes/reactivity/signals.mdx @@ -0,0 +1,73 @@ +--- +title: "Signals" +order: 2 +--- + +Signals are the **primary way to manage state** in a Solid application. +They store values, notify dependents when those values change, and form the [foundation of reactivity](/reactivity/overview). + +You can use signals for any kind of state: +- simple values (strings, numbers) +- complex values (objects, arrays) +- application state (current user, theme, page, etc.) + +## What is a Signal? + +A **signal** is a reactive value container. +It holds a value and provides a **getter** to read the value and a **setter** to update it. +When the value changes, it automatically triggers updates in any dependent computations. + +They can be thought of as a **reactive variable**. + +## Create a Signal + + +Use [`createSignal`](/reference/basic-reactivity/create-signal) from `solid-js`: + +```tsx +import { createSignal } from "solid-js"; + +const [count, setCount] = createSignal(0); +// ^ getter ^ setter +``` + +:::note +The [getter, setter] syntax uses [array destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)(). +::: + + +## Read a Signal's Value + +To read the current value of a signal, simply call the getter function: + +```tsx +console.log(count()); // 0 +``` + +## Update a Signal's Value + +To update the value of a signal, call the setter function with the new value: + +```tsx +setCount(1); +console.log(count()); // 1 +``` + +## Reactivity in Action + +Signals are **reactive**: when used inside a tracking scope, they automatically notify dependents when updated. + +```tsx +function Counter() { + const [count, setCount] = createSignal(0); + const increment = () => setCount(prev => prev + 1); + + return ( +
+ Count: {count()} {/* Updates when `count` changes */} + +
+ ); +} +``` + diff --git a/src/routes/reactivity/stores.mdx b/src/routes/reactivity/stores.mdx new file mode 100644 index 000000000..5a5384762 --- /dev/null +++ b/src/routes/reactivity/stores.mdx @@ -0,0 +1,100 @@ +--- +title: "Stores" +order: 5 +--- + +Stores are a state management primitive in Solid that provide a convenient, centralized way to handle structured data. +Unlike signals, which are best suited for primitive values, stores are better for managing complex data structures like objects and arrays: + +- They provide fine-grained reactivity, meaning only the parts of the store that are accessed will trigger updates when they change. +- They support **nested reactivity,** so you can track and update deeply nested properties without losing reactivity. +- They make working with complex state easier while avoiding duplication or unnecessary recomputation. + +Stores are built on top of Solid's reactive system, leveraging [JavaScript's proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) to track property access and changes. + +## Creating a Store + +To create a store, you can use the `createStore` function from the `solid-js/store` package. +This function takes an initial value and returns a tuple containing the store and a setter function to update it. + +```tsx +import { createStore } from "solid-js/store" + +// Initialize store +const [store, setStore] = createStore({ + userCount: 3, + users: [ + { + id: 0, + username: "felix909", + location: "England", + loggedIn: false, + }, + { + id: 1, + username: "tracy634", + location: "Canada", + loggedIn: true, + }, + { + id: 2, + username: "johny123", + location: "India", + loggedIn: true, + }, + ], +}) +``` + +## Accessing store values + +Unlike signals, which are functions that need to be called to get their values, stores can be accessed directly like regular objects or arrays. + +```tsx +console.log(store.userCount) // 3 +``` + +Inside a tracking scope, store properties can be accessed directly, and any changes to those properties will trigger updates to the scope. + +:::note + +Stores create signals **lazily**. +This means that a property only becomes reactive once accessed inside a tracking scope. +::: + +```tsx +const App = () => { + const [mySignal, setMySignal] = createSignal("This is a signal.") + const [store, setStore] = createStore({ + userCount: 3, + users: [ + { + id: 0, + username: "felix909", + location: "England", + loggedIn: false, + }, + { + id: 1, + username: "tracy634", + location: "Canada", + loggedIn: true, + }, + { + id: 2, + username: "johny123", + location: "India", + loggedIn: true, + }, + ], + }) + return ( +
+

Hello, {store.users[0].username}

{/* Accessing a store value */} + {mySignal()} {/* Accessing a signal */} +
+ ) +} +``` + +## \ No newline at end of file diff --git a/src/routes/rendering/data.json b/src/routes/rendering/data.json new file mode 100644 index 000000000..1fbb9d7ea --- /dev/null +++ b/src/routes/rendering/data.json @@ -0,0 +1,4 @@ +{ + "title": "Rendering", + "pages": [] +} diff --git a/src/routes/solid-router/concepts/actions.mdx b/src/routes/solid-router/concepts/actions.mdx index 26fba9b4b..0bf425e48 100644 --- a/src/routes/solid-router/concepts/actions.mdx +++ b/src/routes/solid-router/concepts/actions.mdx @@ -13,151 +13,445 @@ tags: version: '1.0' --- -When developing applications, it is common to need to communicate new information to the server based on user interactions. -Actions are Solid Router’s solution to this problem. +Many user interactions in an application involve changing data on the server. +These **mutations** can be challenging to manage, as they require updates to the application's state and proper error handling. +Actions simplify managing data mutations. -## What are actions? +Actions provide several benefits: -Actions are asynchronous processing functions that allow you to submit data to your server and receive a response. -They are isomorphic, meaning they can run either on the server or the client, depending on what is needed. -This flexibility makes actions a powerful tool for managing and tracking data submissions. +- **Integrated state management:** + Solid Router automatically tracks the execution state of an action, simplifying reactive UI feedback. +- **Automatic data revalidation:** + After an action successfully completes, Solid Router revalidates relevant [`queries`](/solid-router/concepts/queries), ensuring the UI reflects the latest data. +- **Progressive enhancement:** + When used with HTML forms, actions enable functionality even if JavaScript is not yet loaded. -### How actions work +## Defining actions -Actions represent the server-side part of an [HTML form](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form). -They handle submissions through POST requests, allowing you to easily use HTML forms to send data. +Actions are defined by wrapping the data-mutation logic with the [`action` function](/solid-router/reference/data-apis/action). -When a user performs an action, such as submitting a form, the data is sent to the server for processing via an action. +```tsx +import { action } from "@solidjs/router"; + +const createTicketAction = action(async (subject: string) => { + const response = await fetch("https://my-api.com/support/tickets", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ subject }), + }); + + if (!response.ok) { + const errorData = await response.json(); + return { ok: false, message: errorData.message }; + } + + return { ok: true }; +}, "createTicket"); +``` + +In this example, an action is defined that creates a support ticket using a remote API. + +## Using actions + +Actions can be triggered in two ways: using a HTML [`
` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/form) or programmatically using the [`useAction` primitive](/solid-router/reference/data-apis/use-action). -### Benefits of using actions +The recommended approach is to use a `` element. +This ensures a robust user experience with progressive enhancement, since the form works even without JavaScript. -1. **Isomorphic**: Since actions can run on both the server and client, you can optimize performance by choosing the best execution environment for your needs. -2. **Asynchronous processing**: Actions handle data submissions asynchronously, ensuring that your application remains responsive. -3. **Simplified data handling**: By using actions, the process of managing and tracking data submissions can be streamlined, reducing the complexity of your application. +For cases where a form is not suitable, the [`useAction` primitive](/solid-router/reference/data-apis/use-action) can be used to trigger the action programmatically. -## Creating actions +### With the `` element -To create an action, use the `action` function from the `@solidjs/router` package. -This function takes an asynchronous function as an argument and returns a new function that can be used to submit data. +Solid Router extends the standard HTML `` element to work with actions. +Form submissions can be handled using action by passing an action to the `action` prop. + +Consider these points when using actions with ``: + +1. The `` element **must** have `method="post"`. +2. The action function will automatically receive the form's data as a [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) object as its first parameter. +3. For SSR environments, a unique name **must** be provided as the second parameter to the `action` function. + This name is used by Solid Router to identify and serialize the action across the client and server. ```tsx import { action } from "@solidjs/router"; -const echo = action(async (message: string) => { - // Simulates an asynchronous operation, such as an API call - await new Promise((resolve, reject) => setTimeout(resolve, 1000)); - console.log(message); -}); +const submitFeedbackAction = action(async (formData: FormData) => { + const message = formData.get("message")?.toString(); + // ... Sends the feedback to the server. +}, "submitFeedback"); + +function FeedbackForm() { + return ( + +