Interactive islands

Islands are interactive UI components integrated into the static HTML layout. Common examples include account menus, login pages, forms, and image galleries.

Nue islands

Nue islands have the following characteristics:

  1. Interactivity: Islands enable dynamic widgets and interactive components, such as forms that send data to your backend, allowing users to engage with your site and enhancing their experience.

  2. Isomorphism: Nue islands can be isomorphic, meaning parts are rendered on the server and parts on the client. This ensures proper content indexing by search engines while providing a responsive, engaging experience for users.

  3. Loose coupling: Islands can be created using Web Components for simple interactions or an HTML-based template syntax for more advanced functionality.

Islands: Nue vs. Astro

Astro Islands are a valuable addition to the JavaScript ecosystem, showcasing separation of concerns and progressive enhancement. However, Nue fully embodies these principles, integrating loose coupling and progressive enhancement as core features. This design choice protects developers from the complexities of JavaScript monoliths, offering a simpler, more efficient experience for the entire application.

Creating an island

Islands are created using the same simple HTML-based template syntax used for layout modules on the server side. They are dynamic HTML components with a .dhtml extension, and their name is set using the @name attribute.

<form ="join-list" .prevent="submit" autocomplete="on">
  <label>
    <span>Your name</span>
    <input type="text" name="name" placeholder="Example: John Doe" required>
  </label>

  <label>
    <span>Your email</span>
    <input type="email" name="email" placeholder="your@email.com" required>
  </label>

  <button>Submit</button>

  <script>
    function submit() {
      // Send the form data with fetch()
    }
  </script>
</form>

The nue.js file

Nue automatically includes a lightweight script (just 2.5 KB, located at /@nue/nue.js) to your page, enabling reactive features on the HTML layout. This script supports loops, conditionals, and re-rendering, allowing for React-like interactivity using a semantic, HTML-based syntax that prioritizes simplicity and accessibility.

Global, area, and page contexts

Islands are defined as dynamic HTML components located in different contexts within the Nue framework:

Multiple islands in a single file

Each .dhtml file can contain multiple islands, enabling related components to be grouped together. For example, blog/islands.dhtml could define a comment form, sharing widget, and related posts section, all reusable across blog entries. This promotes modularity, allowing the server to treat all defined islands as interactive components.

Mounting

Islands can be embedded as custom HTML elements within Markdown content or inside layout modules:

In Markdown content

To integrate an island in Markdown, simply include the following:


Be the first to know about our new releases

[]

In layout modules

To embed an island within a layout module:

<footer ="pagefoot">
  <h3>Join our mailing list</h3>
  <p>Be the first to know about our new releases</p>
  <join-list/>
</footer>

Embedding islands in this way creates interactive components, enhancing user engagement while maintaining the simplicity and performance of a static site.

Isomorphic islands

Isomorphic islands are components rendered on both the server and client, benefiting SEO and accessibility while delivering interactivity on the client side. This approach allows search engines to index your content and ensures seamless user interaction.

Here’s an example of a video component defined in video.html:

<div ="video-player">

  <!-- For SEO and JS-disabled users/browsers -->
  <noscript>
    <video src="https://video.nuejs.org/{videoId}/play_720p.mp4" type="video/mp4" controls>
      Your browser does not support the video tag.
    </video>
  </noscript>

  <!-- The client-side part defined in video.dhtml -->
  <video-player :videoId="videoId" :poster="poster" :width="width"/>

  <!-- Caption and metadata for search engines and AI crawlers -->
  <figcaption :if="caption">{ caption }</figcaption>

</div>

The <noscript> tag provides a fallback for browsers that do not support JavaScript, ensuring the video remains accessible, while the client-side component handles interactivity.

Web components

Web Components are a lightweight, standards-based alternative to interactive islands, ideal for simple interactivity. They enhance static HTML with JavaScript but do not re-render based on internal state, keeping the implementation minimal.

Web Components do not require the nue.js library, offering a no framework approach with minimal code. This is ideal for developers who prioritize efficiency and small code footprints.

Example: Zen mode

The Zen Mode toggle on this website is implemented as a Web Component. Here's the HTML markup:

<div class="zen-toggle">
  <h5>{ lang.zen_mode }</h5>
  <label class="toggle">
    <input type="checkbox" is="zen-toggle">
  </label>
</div>

The Web Component is implemented as follows:

class ZenToggle extends HTMLInputElement {
  constructor() {
    super();
    this.onchange = function() {
      document.documentElement.classList.toggle('zen', this.checked);
    };
  }
}

customElements.define('zen-toggle', ZenToggle, { extends: 'input' });

This ZenToggle component allows users to toggle Zen Mode on and off by checking a box, dynamically applying a Zen-themed style.

React support?!

Islands provide an ideal framework for integrating React into Nue. While React and Nue may seem philosophically different, the architecture of islands allows for a seamless integration of React's concepts, such as hooks, without compromising Nue’s principles of progressive enhancement. This flexibility lets developers use React while keeping the benefits of Nue's lightweight, semantic approach.

This integration enables the gradual transition from traditional JavaScript monoliths to a more semantic, maintainable approach, leading to cleaner, more accessible code. If you’re interested in React support, please join our mailing list and share your thoughts.