### Setup Alpine.js with UIKit Plugins Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/uikit/introduction.md Cherry-pick and register the desired Edge UIKit plugins with Alpine.js. Ensure Alpine.js is started afterwards. This example shows registering the tabs plugin. ```js import Alpine from 'alpinejs' import { tabs } from 'edge-uikit/tabs' /** * Using the tabs plugin. It is required by the * tabs component. */ Alpine.plugin(tabs) Alpine.start() ``` -------------------------------- ### Install Dependencies Source: https://github.com/edge-js/edgejs.dev/blob/main/README.md Install project dependencies after cloning the repository. ```sh cd \nnpm i ``` -------------------------------- ### Run Development Server Source: https://github.com/edge-js/edgejs.dev/blob/main/README.md Start the development server for the docs boilerplate. ```sh npm run dev ``` -------------------------------- ### Install Edge.js v6 (Next) Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/changelog/upgrading-to-v6.md Install the latest version of Edge.js, which is currently tagged as @next. ```sh npm i edge.js@next ``` -------------------------------- ### Install and Create Edge Instance Source: https://context7.com/edge-js/edgejs.dev/llms.txt Install EdgeJS and create an instance pointed at your templates directory. Configure caching for production environments and mount disks for template storage. ```typescript // Install // npm i edge.js import { Edge } from 'edge.js' import { createServer } from 'node:http' const edge = Edge.create({ cache: process.env.NODE_ENV === 'production', // cache compiled templates in production }) // Mount a default disk (all .edge files live here) edge.mount(new URL('./views', import.meta.url)) // Optional: mount named disks for theming edge.mount('uikit', new URL('./themes/uikit', import.meta.url)) const server = createServer(async (req, res) => { const html = await edge.render('home', { username: 'virk' }) res.setHeader('content-type', 'text/html') res.end(html) }) server.listen(3000) ``` ```edge {{-- views/home.edge --}}

Hello {{ username }}

``` -------------------------------- ### Install Edge UIKit Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/uikit/introduction.md Install the Edge UIKit package using npm. This command installs the latest version. ```sh npm i edge-uikit@next ``` -------------------------------- ### Install Edge Markdown Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/digging_deeper/edge-markdown.md Install the edge-markdown plugin using npm. ```sh npm i edge-markdown ``` -------------------------------- ### Install Alpine.js Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/uikit/introduction.md Install Alpine.js as a development dependency. This is required for frontend interactivity. ```sh npm i -D alpinejs ``` -------------------------------- ### Install Iconify JSON Bundle Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/digging_deeper/iconify.md Install a specific Iconify icon set bundle, such as HeroIcons, from npm. ```sh npm i @iconify-json/heroicons ``` -------------------------------- ### Project Structure Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/getting_started.md Example project structure with a views directory for Edge templates. ```tree .\n├── views\n│ └── home.edge\n├── index.js\n└── package.json ``` -------------------------------- ### Install Edge.js Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/getting_started.md Install the Edge.js package using npm. Ensure your project uses ES modules. ```sh npm i edge.js ``` -------------------------------- ### Basic Server Setup with Edge.js Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/getting_started.md Set up a Node.js HTTP server to render Edge templates. Mounts the 'views' directory and renders 'home.edge' on requests. ```ts import { Edge } from 'edge.js'\nimport { createServer } from 'node:http'\n\n// highlight-start\nconst edge = Edge.create()\nedge.mount(new URL('./views', import.meta.url))\n// highlight-end\n\nconst server = createServer(async (req, res) => {\n\t// highlight-start\n const data = { username: 'virk' }\n const html = await edge.render('home', data)\n\t// highlight-end\n\n res.setHeader('content-type', 'text/html')\n res.end(html)\n})\n\nserver.listen(3000) ``` -------------------------------- ### Install Edge Iconify Plugin Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/digging_deeper/iconify.md Install the edge-iconify npm package to enable Iconify integration. ```sh npm i edge-iconify ``` -------------------------------- ### Example Edge Template Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/getting_started.md A simple Edge template that displays a username. This file should be placed in the 'views' directory. ```edge \n\n\n\t\n\n\n

\n Hello {{ username }}\n

\n\n ``` -------------------------------- ### Get Specific Props Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/components/props.md Extract a subset of props based on a list of keys using `$props.only(['key1', 'key2'])`. The example then retrieves the 'text' prop from this subset. ```edge {{ $props.only(['text', 'class']).get('text') }} ``` -------------------------------- ### Input Component with Merged Custom Classes Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/components/props.md Example of rendering an input component with both default and custom classes. The output demonstrates how multiple classes are combined. ```edge @input({ type: 'text', name: 'title', id: 'title', class: [ 'input-medium', 'input-rounded' ] }) ``` -------------------------------- ### Install and Configure Edge Markdown Plugin Source: https://context7.com/edge-js/edgejs.dev/llms.txt Install the `edge-markdown` package and configure it within your Edge.js application to enable Markdown rendering with features like Shiki syntax highlighting, frontmatter, and TOC generation. ```sh npm i edge-markdown ``` ```ts import edge from 'edge.js' import { edgeMarkdown } from 'edge-markdown' edge.use(edgeMarkdown({ highlight: true, // Shiki syntax highlighting allowHTML: true, // allow raw HTML in Markdown toc: { enabled: true, maxDepth: 2 }, shiki: { theme: 'github-dark', langs: ['ts', 'js', 'shell'] }, remarkPlugins: [], rehypePlugins: [], })) ``` -------------------------------- ### Configure Shiki Syntax Highlighting Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/digging_deeper/edge-markdown.md Customize Shiki's theme and supported languages for syntax highlighting. Ensure the specified languages are installed in Shiki. ```typescript import { edgeMarkdown } from 'edge-markdown' edge.use(edgeMarkdown({ shiki: { theme: 'github-dark', langs: ['javascript', 'typescript', 'json'] } })) ``` -------------------------------- ### Input Component with Default Classes Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/components/props.md Example of rendering an input component with default classes applied. The output shows the merged class attribute. ```edge @input({ type: 'text', name: 'title', id: 'title', }) ``` -------------------------------- ### Use a Card Component with Named Slots Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/components/slots.md This example demonstrates how to use the `card` component and provide content for its 'header' and 'content' slots. The content within the `@slot` and `@end` tags is rendered in the respective slot locations within the component. ```edge @card({ class: ['card-lg', 'card-shadow'] }) @slot('header') Quick start @end @slot('content')

Start building your next project in minutes

@end @end ``` -------------------------------- ### Edge Components with Accordion Example Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/introduction.md Define and use components in Edge, demonstrated here with an accordion structure. Components allow for reusable UI elements with slots and props. ```edge @accordion() @accordion.item({ title: 'What is Edge?' }) Edge is a template engine for Node.js @end @accordion.item({ title: 'Why should I use Edge?' }) Because you need a template engine 🤷🏻‍♂️ @end @accordion.item({ title: 'How can I support Edge?' }) By becoming a sponsor on Github @end @end ``` -------------------------------- ### Use a Card Component with a Main Slot Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/components/slots.md This example shows how to use a component that accepts a 'title' prop and uses a 'main' slot for its content. The content provided directly within the component tag is rendered by the `main` slot. ```edge @card({ title: 'Quick start' })

Start building your next project in minutes

@end ``` -------------------------------- ### Render Templates from Named Disks Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/getting_started.md Render templates by prefixing the disk name to the template path, using the format 'diskName::templatePath'. Example: 'classic::home'. ```ts await edge.render('classic::home')\nawait edge.render('mono::pages/posts/index') ``` -------------------------------- ### Render Components with Props Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/components/introduction.md Use the `@component` tag to render components, passing the template path and props as arguments. This example shows rendering a button component twice with different text and types. ```edge
@!component('components/button', { text: 'Login' }) @!component('components/button', { text: 'Cancel', type: 'reset' })
``` -------------------------------- ### Reference Component from Named Disk as Tag Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/components/introduction.md Components from named disks can be referenced as tags by prefixing the disk name. This example shows referencing an 'input' component from the 'uikit' disk. ```edge {{-- Component as a tag from the uikit disk --}} @!uikit.input() {{-- Via component tag --}} @!component('uikit::input') ``` -------------------------------- ### AST for Raw String Argument Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/digging_deeper/creating-custom-tags.md Example of the AST generated when the '@reverse' tag is called with a raw string literal argument. ```json { "type": "Literal", "start": 0, "end": 13, "loc": { "start": { "line": 1, "column": 9 }, "end": { "line": 1, "column": 13 } }, "value": "hello world", "raw": "'hello world'" } ``` -------------------------------- ### AST for Function Call Argument Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/digging_deeper/creating-custom-tags.md Example of the AST generated when the '@reverse' tag is called with a function call as an argument. ```json { "type": "CallExpression", "start": 0, "end": 13, "loc": { "start": { "line": 1, "column": 9 }, "end": { "line": 1, "column": 13 } }, "callee": { "type": "MemberExpression", "object": { "type": "Identifier", "name": "state" }, "computed": false, "property": { "type": "Identifier", "start": 0, "end": 11, "loc": { "start": { "line": 1, "column": 9 }, "end": { "line": 1, "column": 11 } }, "name": "getUserName" } }, "arguments": [], "optional": false } ``` -------------------------------- ### Use Card Component with Scoped Slots Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/components/slots.md This example shows how to consume data passed from the component to its slots. The slot definition now accepts an argument (e.g., `componentState`) which receives the data object passed from the component, allowing access to `componentState.cardSize`. ```edge @card() @slot('header') Quick start @end // highlight-start @slot('content', componentState)

I am a {{ componentState.cardSize }} card

@end // highlight-end @end ``` -------------------------------- ### AST for Variable Reference Argument Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/digging_deeper/creating-custom-tags.md Example of the AST generated when the '@reverse' tag is called with a variable reference as an argument. ```json { "type": "MemberExpression", "object": { "type": "Identifier", "name": "state" }, "computed": false, "property": { "type": "Identifier", "start": 0, "end": 8, "loc": { "start": { "line": 1, "column": 9 }, "end": { "line": 1, "column": 8 } }, "name": "username" } } ``` -------------------------------- ### Use Card Component with Named Slots in Edge.js Source: https://context7.com/edge-js/edgejs.dev/llms.txt Example of calling the 'card' component and providing content for the 'header' slot and the main content. The content outside named slots is rendered in the main slot. ```edge @card({ class: ['card-lg', 'card-shadow'] }) @slot('header') Quick Start @end

Everything outside a named slot goes to the main slot.

@end ``` -------------------------------- ### Async/Await in Edge Templates Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/introduction.md Execute asynchronous operations directly within your Edge templates using the @let directive and await keyword. Ensure the operation is awaited to get the correct result. ```edge @let(payments = await user.getPayments()) You have made {{ payments.length }} payments so far. ``` -------------------------------- ### Conditional Rendering with @if and @unless Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/conditionals.md Use the @unless tag as a shorthand for @if(!condition) to render content when a condition is falsy. Both examples achieve the same result of displaying a message when the account is not active. ```edge // title: With @if tag @if(!account.isActive)

Please verify your email address to activate the account

@end ``` ```edge // title: With @unless tag @unless(account.isActive)

Please verify your email address to activate the account

@end ``` -------------------------------- ### Configure Website Links and Settings Source: https://github.com/edge-js/edgejs.dev/blob/main/README.md Configure website links, file edit base URL, and copyright information. The menu and search configurations are optional. ```json { "links": { "home": { "title": "Your project name", "href": "/" }, "github": { "title": "Your project on Github", "href": "https://github.com/dimerapp" } }, "fileEditBaseUrl": "https://github.com/dimerapp/docs-boilerplate/blob/develop", "copyright": "Your project legal name" } ``` ```json { "menu": [ { "href": "/docs/introduction", "title": "Docs" }, { "href": "https://blog.project.com", "title": "Blog" }, { "href": "https://github.com/project/releases", "title": "Releases" } ] } ``` ```json { "search": { "appId": "", "indexName": "", "apiKey": "" } } ``` -------------------------------- ### Register Iconify Plugin with Edge Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/digging_deeper/iconify.md Register the edgeIconify plugin with your Edge.js instance after installation. ```ts import edge from 'edge.js' import { edgeIconify } from 'edge-iconify' edge.use(edgeIconify) ``` -------------------------------- ### Get Prop Value Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/components/props.md Retrieve the value of a specific prop using the `$props.get('propName')` method. ```edge {{ $props.get('text') }} ``` -------------------------------- ### Mount Multiple Named Disks for Theming Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/getting_started.md Register multiple named disks (e.g., 'elegant', 'classic', 'mono') to manage templates from different theme directories. Useful for theming systems. ```ts const BASE_URL = new URL('./', import.meta.url)\n\nedge.mount(\n 'elegant',\n new URL('themes/elegant', BASE_URL)\n)\n\nedge.mount(\n 'classic',\n new URL('themes/classic', BASE_URL)\n)\n\nedge.mount(\n 'mono',\n new URL('themes/mono', BASE_URL)\n) ``` -------------------------------- ### Configure Compatibility Plugin Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/changelog/upgrading-to-v6.md Use the 'migrate' plugin to maintain compatibility with v5 features if your project is not ready for all breaking changes. ```ts import edge from 'edge.js' import { migrate } from 'edge.js/plugins/migrate' edge.use(migrate) ``` -------------------------------- ### Project Folder Structure Source: https://github.com/edge-js/edgejs.dev/blob/main/README.md Overview of the directory structure for the AdonisJS docs boilerplate. ```tree .\n├── assets\n│ ├── app.css\n│ └── app.js\n├── bin\n│ ├── build.ts\n│ └── serve.ts\n├── content\n│ ├── docs\n│ └── config.json\n├── src\n│ ├── bootstrap.ts\n│ └── collections.ts\n├── templates\n│ ├── elements\n│ ├── layouts\n│ ├── partials\n│ └── docs.edge\n├── vscode_grammars\n│ ├── dotenv.tmLanguage.json\n│ └── main.ts\n├── package-lock.json\n├── package.json\n├── README.md\n├── tsconfig.json\n└── vite.config.js ``` -------------------------------- ### Component Usage with Props in Edge.js Source: https://context7.com/edge-js/edgejs.dev/llms.txt Demonstrates how to call a component and pass props, including conditional attributes and custom classes. The output shows the resulting HTML. ```edge {{-- Caller usage --}} @!input({ name: 'email', type: 'email', placeholder: 'you@example.com', class: ['input-lg', 'input-rounded'], label: 'Email address', }) {{-- Output: --}} @!input({ removeExistingStyles: true, class: ['custom-input'] }) {{-- Output: --}} ``` -------------------------------- ### Render Input Component with Props Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/components/props.md Render the input component and pass specific props like name and placeholder. This demonstrates how to customize component behavior and appearance. ```edge @!input({ name: 'title', placeholder: 'Enter post title' }) @!input({ name: 'slug', placeholder: 'Enter post slug' }) ``` -------------------------------- ### Loop Over Array with Index in Edge.js Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/loops.md Iterate over an array named 'users' and display both the index (starting from 1) and the username. Useful for numbered lists or when the position matters. ```edge @each((user, index) in users)
  • {{ index + 1 }} {{ user.username }}
  • @end ``` -------------------------------- ### Markdown with Shiki Transformers Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/digging_deeper/edge-markdown.md Demonstrates Shiki's transformers for diffing, line highlighting, and word highlighting using inline comments within Markdown code blocks. The metadata is accessible via `node.properties`. ```markdown ```ts title=start/routes.ts console.log('Highlighted') // [!code highlight] console.log('Not highlighted') console.log('hewwo') // [!code --] console.log('hello') // [!code ++] // [!code word:Hello] const message = 'Hello World' ``` ``` -------------------------------- ### edge.render Source: https://context7.com/edge-js/edgejs.dev/llms.txt Renders a template file relative to the mounted disk root. Returns a Promise. ```APIDOC ## edge.render ### Description Renders a template file relative to the mounted disk root. Returns a `Promise`. ### Method `edge.render(templateName: string, data?: any): Promise` ### Parameters #### Path Parameters - **templateName** (string) - Required - The name of the template file to render. - **data** (any) - Optional - The data to pass to the template. ### Request Example ```ts import { Edge } from 'edge.js' const edge = Edge.create() edge.mount(new URL('./views', import.meta.url)) // Render views/pages/posts/index.edge const html = await edge.render('pages/posts/index', { posts: [ { id: 1, title: 'Hello Edge', author: 'virk' }, { id: 2, title: 'Components 101', author: 'romain' }, ], }) console.log(html) // Render from a named disk const uiHtml = await edge.render('uikit::components/button', { text: 'Submit' }) ``` ### Response #### Success Response (Promise) - **html** (string) - The rendered HTML content. ``` -------------------------------- ### Provide State Down Component Tree in Edge.js Source: https://context7.com/edge-js/edgejs.dev/llms.txt Uses the '@inject' tag to make state available to all descendant components without prop drilling. This example injects a 'map' object. ```edge {{-- views/components/map/index.edge --}} @let(map = { center, zoom, markers: [] }) {{-- Inject state for all children --}} @inject({ map }) {{-- Evaluate slots without rendering output --}} @eval(await $slots.main()) {{-- Now map.markers is populated by marker children --}}
    ``` -------------------------------- ### Customize GitHub Link in Edge.js Header Source: https://github.com/edge-js/edgejs.dev/blob/main/README.md Use the 'github' slot to provide custom markup for the GitHub link in the header. This example includes the star count in the link text. ```edge @component('docs::header', contentConfig) @slots('github') Github (11K+ Stars) @end @end ``` -------------------------------- ### Define a Documentation Entry Source: https://github.com/edge-js/edgejs.dev/blob/main/README.md Define a typical database entry for documentation content. Ensure permalink is unique and contentPath points to the correct markdown file. ```json { "permalink": "introduction", "title": "Introduction", "contentPath": "./introduction.md", "category": "Guides" } ``` -------------------------------- ### Render Markdown Preview Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/digging_deeper/edge-markdown.md Generate a content preview by rendering only the Markdown content before the first `h2` heading using `$markdown.preview`. Returns content, frontmatter, and messages. ```edge @let(doc = await $markdown.preview({ file: absolutePathToMdFile }))
    {{{ doc.content }}}
    ``` -------------------------------- ### Include Basic Partial Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/partials.md Use the @include tag to insert reusable markup fragments from other template files. The path is relative to the template directory. ```edge @include('partials/header')
    The main content goes here
    @include('partials/footer') ``` -------------------------------- ### Use Components as Tags Source: https://context7.com/edge-js/edgejs.dev/llms.txt Files within the `components/` directory can be directly used as tags, with nested paths mapping to tag names (e.g., `form/input.edge` becomes `@form.input`). ```edge @!button({ text: 'Submit', type: 'submit', class: ['btn-primary'] }) @modal() @slot('header')

    Confirm Delete

    @end @slot('content')

    This action cannot be undone.

    @end @slot('footer') @!button({ text: 'Delete', class: ['btn-danger'] }) @!button({ text: 'Cancel', type: 'reset' }) @end @end ``` -------------------------------- ### Use the Notification Tag in a Template Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/digging_deeper/creating-custom-tags.md This example demonstrates how to use the custom 'notification' tag within an Edge.js template. It shows how to pass notification data to the template and how the tag renders conditional content. ```edge @notification('success')

    {{ notification.message }}

    @end ``` ```typescript const notifications = { success: 'Settings saved successfully' } const output = await edge.renderRaw(` @notification('success')

    {{ notification.message }}

    @end `, { notifications }) ``` -------------------------------- ### Create New Collections in TypeScript Source: https://github.com/edge-js/edgejs.dev/blob/main/README.md Define new collections using the Collection class, specifying the database file path, renderer, and URL prefix. Ensure to call `collection.boot()` after configuration. ```typescript // Docs const docs = new Collection() .db(new URL('../content/docs/db.json', import.meta.url)) .useRenderer(renderer) .urlPrefix('/docs') await docs.boot() // API reference const apiReference = new Collection() .db(new URL('../content/api_reference/db.json', import.meta.url)) .useRenderer(renderer) .urlPrefix('/api') await apiReference.boot() export const collections = [docs, apiReference] ``` -------------------------------- ### Serialize Props to HTML Attributes in Edge.js Source: https://context7.com/edge-js/edgejs.dev/llms.txt Use the $props API to merge, filter, and serialize incoming props into HTML attributes for a component. This example shows merging defaults and excluding specific props. ```edge {{-- Serialize ALL props to HTML attributes, merging in defaults --}} {{-- Conditional merge: add defaults only when removeExistingStyles is falsy --}} ``` -------------------------------- ### Push Content to the Top of a Stack Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/stacks.md Use the `@pushToTop` tag to prepend content to a specified stack. This is useful for adding elements at the beginning of a stack, such as headers or important notices. ```edge @pushTo('world')

    hello!

    @end @pushToTop('world')

    hey!

    @end ``` -------------------------------- ### edge.renderSync Source: https://context7.com/edge-js/edgejs.dev/llms.txt Synchronous version of `edge.render`. Uses synchronous filesystem APIs. ```APIDOC ## edge.renderSync ### Description Same as `render` but uses synchronous filesystem APIs. Prefer `render` in production code. ### Method `edge.renderSync(templateName: string, data?: any): string` ### Parameters #### Path Parameters - **templateName** (string) - Required - The name of the template file to render. - **data** (any) - Optional - The data to pass to the template. ### Request Example ```ts const html = edge.renderSync('home', { username: 'virk' }) console.log(html) // synchronous string output ``` ### Response #### Success Response (string) - **html** (string) - The rendered HTML content. ``` -------------------------------- ### renderSync Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/getting_started.md The `renderSync` method renders template files using synchronous APIs. It's recommended to use the asynchronous `render` method when possible. ```APIDOC ## renderSync ### Description The `renderSync` method is similar to the `render`. However, it uses synchronous APIs under the hood to read and render the template files. We recommend using the `render` method over the `renderSync` method. ### Method ```ts const html = edge.renderSync('home') console.log(html) ``` ``` -------------------------------- ### Customize Theme Switcher Button in Edge.js Header Source: https://github.com/edge-js/edgejs.dev/blob/main/README.md Define custom markup for the theme switcher button using the 'themeSwitcher' slot. This example shows conditional rendering for dark and light mode labels based on a store's dark mode setting. ```edge @component('docs::header', contentConfig) @slots('themeSwitcher') Dark Light @end @end ``` -------------------------------- ### Edge.js Component Rendering (@!component) Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/syntax_specification.md Illustrates the correct syntax for rendering components using the @!component tag. This includes basic component calls and calls with data objects. ```edge @!component('button') ``` ```edge @!component( 'button', { type: 'primary' } ) ``` -------------------------------- ### Render Template using render API Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/getting_started.md Render a template using the 'render' method, providing the template path and an optional data object. Returns the rendered HTML as a string. ```ts const html = await edge.render('home')\nconsole.log(html) ``` -------------------------------- ### Render Recipe Data with Edge.js Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/loops.md This snippet demonstrates how to pass a JavaScript object containing food ingredients and their amounts to an Edge.js template for rendering. ```typescript await edge.render('recipes', { food: { ketchup: '5 tbsp', mustard: '1 tbsp', pickle: '0 tbsp' } }) ``` -------------------------------- ### Configure Edge Markdown Plugin Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/digging_deeper/edge-markdown.md Configure edge-markdown with options for prefix, highlighting, HTML allowance, TOC generation, and plugin integration. ```ts edge.use(edgeMarkdown({ prefix: 'markdown', highlight: true, allowHTML: true, toc: { enabled: true, maxDepth: 2, }, remarkPlugins: [], rehypePlugins: [], components: {}, allowedTags: [], hooks: [ (node) => {}, ] })) ``` -------------------------------- ### Render Markdown from File Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/digging_deeper/edge-markdown.md Use the @markdown tag to render content from a Markdown file. ```edge @markdown({ file: absolutePathToMdFile, }) ``` -------------------------------- ### Include Partial from Different Disk Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/partials.md Include partials stored on different disks by prefixing the disk name to the template path, separated by '::'. ```edge @include('shared::partials/header') @include('shared::partials/footer') ``` -------------------------------- ### Test the Reverse Tag Implementation Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/digging_deeper/creating-custom-tags.md Demonstrates how to test the 'reverse' tag with raw strings, variable references, and function calls. Ensure the tag correctly reverses the provided input. ```typescript // With a raw string assert.equal(await edge.renderRaw(`@reverse('virk')`), 'kriv') // With variable reference assert.equal(await edge.renderRaw(`@reverse(username)`, { username: 'virk' }), 'kriv') // With function call assert.equal(await edge.renderRaw(`@reverse(getUserName())`, { getUserName() { return 'virk' } }), 'kriv') ``` -------------------------------- ### Define a Stack in Layout Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/stacks.md Use the `@stack` tag to create a named placeholder in your main layout file. This stack can then be targeted by other templates to push content. ```edge @stack('js')
    @stack('world') @!dialog()
    ``` -------------------------------- ### renderRawSync Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/getting_started.md The `renderRawSync` method is the synchronous version of `renderRaw`, rendering raw text templates using synchronous APIs. ```APIDOC ## renderRawSync ### Description The `renderRawSync` method is the same as `renderRaw` but uses synchronous APIs under the hood. ### Method ```ts const template = `

    Hello {{ username || 'Guest' }}!

    ` edge.renderRawSync(template, { username: 'virk' }) ``` ``` -------------------------------- ### Use Layout with Slots in a Welcome Page Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/components/layouts.md This EdgeJS template demonstrates how to use a defined layout (`@layout.app`) and pass a title, meta slot content, and main slot content. The `@slot` directive is used to define the content for specific slots within the layout. ```edge // title: views/welcome.edge @layout.app({ title: "Welcome page title" }) @slot('meta') @endslot @slot('main')

    Hello world

    @endslot @end ``` -------------------------------- ### Render Template File with EdgeJS Source: https://context7.com/edge-js/edgejs.dev/llms.txt Render a template file from the mounted disk root. Supports rendering from named disks using the `diskName::templatePath` syntax. ```typescript import { Edge } from 'edge.js' const edge = Edge.create() edge.mount(new URL('./views', import.meta.url)) // Render views/pages/posts/index.edge const html = await edge.render('pages/posts/index', { posts: [ { id: 1, title: 'Hello Edge', author: 'virk' }, { id: 2, title: 'Components 101', author: 'romain' }, ], }) console.log(html) // Render from a named disk const uiHtml = await edge.render('uikit::components/button', { text: 'Submit' }) ``` -------------------------------- ### Edge.js Conditional Rendering (@if) Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/syntax_specification.md Demonstrates the correct syntax for conditional rendering using @if and @end. Ensure proper spacing and structure for valid conditional blocks. ```edge @if(username) Hello @end ``` ```edge @if( username )

    Hello

    @end ``` -------------------------------- ### Define an Input Component with Props Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/components/props.md Define a reusable input component that accepts props for type, placeholder, name, and value. Default values are provided for type and placeholder. ```edge // title: views/components/input.edge ``` -------------------------------- ### Add Iconify Collection and Register Plugin Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/digging_deeper/iconify.md Load an Iconify icon collection (e.g., HeroIcons) and register the plugin with Edge.js. ```ts import { Edge } from 'edge.js' // highlight-start import { edgeIconify, addCollection } from 'edge-iconify' import { icons as heroIcons } from '@iconify-json/heroicons' /** * Add heroIcons collection */ addCollection(heroIcons) // highlight-end const edge = Edge.create() /** * Register the plugin */ edge.use(edgeIconify) ``` -------------------------------- ### Render Raw Template String Source: https://context7.com/edge-js/edgejs.dev/llms.txt Render a template directly from a string without reading from disk. Useful for dynamic templates or testing. ```typescript const template = `
      @each(user in users)
    • {{ user.username }} — {{ user.role }}
    • @end
    ` const html = await edge.renderRaw(template, { users: [ { username: 'virk', role: 'admin' }, { username: 'romain', role: 'editor' }, ], }) // Output: //
      //
    • virk — admin
    • //
    • romain — editor
    • //
    ``` -------------------------------- ### Include Reusable Template Fragments with @include and @includeIf Source: https://context7.com/edge-js/edgejs.dev/llms.txt Incorporate reusable template sections (partials) into your main templates. Partials share the full state of the parent template. @includeIf conditionally renders a partial. ```edge {{-- Include from default disk --}} @include('partials/header')
    @include('partials/sidebar')
    {{ content }}
    @include('partials/footer') {{-- Include from a named disk --}} @include('shared::partials/header') {{-- Conditionally include only when comments exist --}} @includeIf(post.comments.length, 'partials/comments') ``` -------------------------------- ### Basic @inject Decorator Usage Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/components/provide_inject.md Demonstrates the fundamental usage of the @inject tag to share a state object with child components. The @inject tag must be called before rendering or evaluating component slots. ```edge @let(sharedState = {}) @inject(sharedState) ``` -------------------------------- ### Push Content Once to a Stack Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/stacks.md Use the `@pushOnceTo` tag to add content to a specific stack, ensuring it's only added the first time the tag is encountered. This is ideal for preventing duplicate script tags or other elements. ```edge @pushOnceTo('js') @end ``` -------------------------------- ### String Truncation Helpers: `truncate` and `excerpt` Source: https://context7.com/edge-js/edgejs.dev/llms.txt Utilize `truncate` to shorten strings while respecting word boundaries, and `excerpt` to strip HTML tags before truncating. Both support custom suffixes. ```edge {{-- truncate: respects word boundaries by default --}} {{ truncate(post.title, 40) }} {{ truncate(post.title, 40, { completeWords: false, suffix: ' …' }) }} {{-- excerpt: strips HTML tags before truncating --}} {{ excerpt(post.body, 160) }} {{ excerpt(post.body, 160, { suffix: ' [Read more]' }) }} ``` -------------------------------- ### Push Content to a Stack Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/stacks.md Use the `@pushTo` tag to append content to a specified stack. This tag can be used multiple times, and each invocation will add its content to the stack. ```edge @pushTo('world')

    hello!

    @end ``` -------------------------------- ### Basic Text Interpolation in Edge Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/introduction.md Use double curly braces to output dynamic values like user data. This is the most basic way to render variables. ```edge Hello {{ user.username }}! ``` -------------------------------- ### Define New Variable with @let Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/changelog/upgrading-to-v6.md Use the @let tag to define new variables, replacing the old @set('variable', 'value') syntax. ```edge @let(username = 'virk') ``` -------------------------------- ### Converting AST to String Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/digging_deeper/creating-custom-tags.md Demonstrates how to convert a mutated AST back into a JavaScript expression string using the `.stringify()` utility method within the tag compilation process. ```typescript const reverse: TagContract = { block: false, seekable: true, tagName: 'reverse', compile(parser, buffer, token) { const expression = parser.utils.transformAst( parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename), token.filename, parser ) // highlight-start console.log(parser.utils.stringify(expression))) // highlight-end } } ``` -------------------------------- ### Express.js Middleware for Isolated Locals Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/templates_state.md Demonstrates how to use Express.js middleware to create an isolated Edge renderer for each request and share request-specific data using `.share()`. ```typescript app.use(function (req, res) { res.view = edge.createRenderer() }) app.use(function (req, res) { res.view.share({ url: req.url }) }) app.use(function (req, res) { res.view.share({ user: req.auth.user }) }) // Finally render a template app.get('/posts', async (req, res) => { const html = await res.view.render('posts') res.send(html) }) ``` -------------------------------- ### Mount Default Disk for Templates Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/getting_started.md Register the 'views' directory as the default disk for Edge.js to locate templates. Allows rendering templates using relative paths. ```ts const BASE_URL = new URL('./', import.meta.url)\n\nedge.mount(new URL('views', BASE_URL))\n\n/**\n * Render home.edge file from\n * {BASE_URL/views} directory\n */\nawait edge.render('home')\n\n/**\n * Render pages/posts/index.edge file from\n * {BASE_URL/views} directory\n */\nawait edge.render('pages/posts/index') ``` -------------------------------- ### Synchronous Raw Text Template Rendering with renderRawSync Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/getting_started.md Use `renderRawSync` for synchronous rendering of raw text templates. This method is the synchronous counterpart to `renderRaw`. ```typescript const template = `

    Hello {{ username || 'Guest' }}!

    ` edge.renderRawSync(template, { username: 'virk' }) ``` -------------------------------- ### renderRaw Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/getting_started.md The `renderRaw` method allows you to render raw text as a template, supporting dynamic data. ```APIDOC ## renderRaw ### Description The `renderRaw` method allows you to render raw text as a template. ### Method ```ts const template = `

    Hello {{ username || 'Guest' }}!

    ` await edge.renderRaw(template, { username: 'virk' }) ``` ``` -------------------------------- ### Usage of Map Component with Markers in Edge.js Source: https://context7.com/edge-js/edgejs.dev/llms.txt Shows how to use the 'map' component and its nested 'map.marker' components. The marker data is collected via the injected context. ```edge {{-- Usage --}} @map({ center: [-84, 35], zoom: 3 }) @!map.marker({ lat: 37.8225, lon: -122.0024, label: 'San Francisco' }) @!map.marker({ lat: 40.6483, lon: -74.0237, label: 'New York' }) @end ``` -------------------------------- ### Create a Button Component Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/components/introduction.md Define a reusable button component. It accepts `type` and `text` props, with `type` defaulting to 'submit'. ```edge // title: views/components/button.edge ``` -------------------------------- ### edge.renderRawSync Source: https://context7.com/edge-js/edgejs.dev/llms.txt Synchronous version of `edge.renderRaw`. Renders a raw template string synchronously. ```APIDOC ## edge.renderRawSync ### Description Synchronous raw render. Renders a raw template string synchronously. ### Method `edge.renderRawSync(templateString: string, data?: any): string` ### Parameters #### Path Parameters - **templateString** (string) - Required - The raw template string to render. - **data** (any) - Optional - The data to pass to the template. ### Request Example ```ts const html = edge.renderRawSync(`Hello {{ name || 'Guest' }}!`, { name: 'virk' }) // => "Hello virk!" ``` ### Response #### Success Response (string) - **html** (string) - The rendered HTML content. ``` -------------------------------- ### Desired API for Map and Markers Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/components/provide_inject.md This is the target syntax for rendering a map with multiple markers using Edge components. ```edge @map({ center: [-84, 35], zoom: 3 }) @!map.marker({ lat: 37.8225, lon: -122.0024, label: 'Edge Body Shaping' }) @!map.marker({ lat: 33.8981, lon: -118.4169, label: 'Edge Barbershop & Essentials' }) @!map.marker({ lat: 29.723, lon: -95.4189, label: 'Edge Waxing Studio' }) @!map.marker({ lat: 28.3378, lon: -81.3966, label: 'Edge 30 Nutritional Consultants' }) @!map.marker({ lat: 40.6483, lon: -74.0237, label: 'Edge Brands LLC' }) @end ``` -------------------------------- ### Render Modal Component with Slots Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/components/introduction.md Render the modal component using its filename as a tag. Inject content into the named slots using the `@slot` directive. ```edge @modal() @slot('header')

    Delete post

    @end @slot('content')

    You are about to delete the post permanently

    @end @slot('footer') @end @end ``` -------------------------------- ### Basic Interpolation Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/interpolation.md Embed a username variable directly into a string. The output will replace the {{ username }} placeholder with the provided value. ```edge Hello {{ username }}! ``` -------------------------------- ### Render Components with @component and @!component Source: https://context7.com/edge-js/edgejs.dev/llms.txt Use @component for block-style component rendering with slots, and @!component for self-closing components. Components can also be referenced by filename as tags. ```edge {{-- Auto-close (self-closing) --}} @!component('components/button', { text: 'Cancel', type: 'reset' }) {{-- Block form with slot content --}} @component('components/button', { class: ['btn-primary'] }) Save Changes @end {{-- From a named disk --}} @!component('uikit::components/input', { name: 'email', type: 'email' }) ``` -------------------------------- ### Synchronous Template Rendering with renderSync Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/getting_started.md Use `renderSync` for synchronous template rendering. It's recommended to use the asynchronous `render` method instead. ```typescript const html = edge.renderSync('home') console.log(html) ``` -------------------------------- ### Define Global Configuration Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/templates_state.md Use `edge.global` to define global state accessible by all templates. This is useful for sharing website configurations like theme settings or navigation menus. ```typescript edge.global('config', { colorScheme: 'dark', menu: [], socialLinks: [], }) ``` -------------------------------- ### Define a Modal Component Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/components/introduction.md Create a modal component with named slots for header, content, and footer. This allows for flexible content injection. ```edge // title: views/component/modal.edge ``` -------------------------------- ### Pretty-print values with inspect helper Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/debugging.md Use the `inspect` helper to pretty-print complex data structures for debugging. The output is HTML and best viewed in a browser. ```edge {{ inspect({ a: 1, b: [3, 4, undefined, null], c: undefined, d: null, e: { regex: /^x/i, buf: Buffer.from('abc'), }, balance: BigInt(100), id: Symbol('1234'), scores: new Set([1, 2, 3]), classes: new Map([['english', '1st'], ['maths', '2nd']]), currentScores: new WeakSet([[1, 2, 3]]), currentClasses: new WeakMap([[['english', '1st'], ['maths', '2nd']]]), now: new Date() }) }} ``` -------------------------------- ### Define and Render Slots in Hero Component Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/digging_deeper/edge-markdown.md Use the `#` tag to define slots in Markdown components and `@markdownSlot` to render their content within an Edge template. The default slot is rendered without a name. ```mdc ::hero Default slot text #description This will be rendered inside the `description` slot. :: ``` ```edge // title: components/markdown/hero.edge

    @markdownSlot()

    @markdownSlot('description')
    ``` -------------------------------- ### Update edge-stacks and edge-iconify Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/changelog/upgrading-to-v6.md Ensure you update related packages like edge-stacks and edge-iconify to their next versions. ```sh npm i edge-stacks@next npm i edge-iconify@next ``` -------------------------------- ### Reference Component from Named Disk Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/components/introduction.md Components stored in named disks can be referenced by prefixing the disk name to the component path. ```edge @!component('uikit::components/button', { text: 'Login' }) ``` -------------------------------- ### Define Layout with Stack Placeholders in Edge.js Source: https://context7.com/edge-js/edgejs.dev/llms.txt A main layout defines placeholders using '@stack' for 'head_scripts' and 'body_scripts'. Content pushed to these stacks will be rendered in the layout. ```edge {{-- views/components/layouts/main.edge --}} @stack('head_scripts')
    {{{ await $slots.main() }}}
    @stack('body_scripts') ``` -------------------------------- ### Generate Excerpt from HTML with excerpt Source: https://github.com/edge-js/edgejs.dev/blob/main/content/docs/digging_deeper/helpers.md The excerpt helper removes HTML tags from a string, truncates it, and returns plain text. It's ideal for generating summaries from HTML content. Options for word completion and suffix are available. ```edge {{ excerpt( '

    Hello, this is a dummy post

    ', 20 ) }} ``` ```edge {{ excerpt( '

    Hello, this is a dummy post

    ', 20, { completeWords: false } ) }} ``` ```edge {{ excerpt( '

    Hello, this is a dummy post

    ', 20, { suffix: ' [Read more]' } ) }} ```