Skip to content

Releases: Jahia/javascript-modules

JavaScript Modules v0.7.0 ☕️

14 May 09:37

Choose a tag to compare

This release adds support for JS<->Java interactions through OSGi services.

New Features

  • JS code can interact with Java code through OSGi services. Usage looks roughly like this:

    import { jahiaComponent, server } from "@jahia/javascript-modules-library";
    
    jahiaComponent(
      {
        nodeType: "javascriptExample:testOSGi",
        name: "default",
        componentType: "view",
      },
      () => <p>{server.osgi.getService("org.example.services.SimpleService").sayHello("World")}</p>,
    );

    The documentation will be updated shortly with more details on how to use this feature. In the meantime, you can check #294 for more examples. If you have feedback on this feature, please reach out to us: calendar.app.google/LigWTiUSDeHmVCwa7

  • JS client files are now minified. This should save up to 1 MB of client-side JavaScript for cold page loads! #269

  • process.env.NODE_ENV is now replaced during the build. This change makes JavaScript Modules more compatible with the rest of the Node.js ecosystem. #263

  • Sourcemaps are generated by default in development mode. #272

Breaking Changes

  • buildNavMenu has been removed. #282

Dependency Updates (#299)

All runtime dependencies have been updated to the latest versions. This includes:

  • i18next: 23.10.1 → 25.0.2 (🚨 Check i18next.com/misc/migration-guide for breaking changes affecting you)
  • react: 19.0.0 → 19.1.0
  • react-i18next: 15.4.0 → 15.5.1
  • styled-jsx: 5.1.6 → 5.1.7

Other Changes

  • All packages of this monorepo are now published to maven/npmjs.com on every commit. You can check the versions tab to install pre-release versions. Be careful, pre-releases do not go through our QA step. #254 and #281
  • You should no longer experience issues with jExperience and page-level personalization. #295
  • GraalVM is now correctly detected. #293

Full Changelog: 0_6_1...0_7_0

JavaScript Modules v0.6.1

07 Apr 06:00

Choose a tag to compare

JavaScript Modules are not compatible with Jahia 8.2.0.x.

This releases enforces that by raising the minimum Jahia version to 8.2.1.0.

JavaScript Modules v0.6.0 📖

27 Mar 09:37

Choose a tag to compare

The new documentation is here! We have completely rewritten the Getting Started guide, read it here.

This release contains new and improved APIs in @jahia/javascript-modules-library. Some of these changes are breaking.

Breaking Changes

Removed useUrlBuilder (#198)

This API was verbose and cumbersome, so we removed the intermediate steps needed to produce a URL out of a node, a module file or an endpoint.

  • To get the URL of a JCR node:

    -import { useUrlBuilder } from "@jahia/javascript-modules-library";
    -const { buildNodeUrl } = useUrlBuilder();
    -const url = buildNodeUrl({ nodePath: currentNode.getPath() });
    +import { buildNodeUrl } from "@jahia/javascript-modules-library";
    +const url = buildNodeUrl(currentNode);

    Additional parameters (e.g. language, mode), can be given as a second object parameter buildNodeUrl(currentNode, { language: "en_US", mode: "edit" })

  • To get the URL of a file exposed by a module:

    -import { useUrlBuilder } from "@jahia/javascript-modules-library";
    -const { buildStaticUrl } = useUrlBuilder();
    -const url = buildStaticUrl({ assetPath: "../dist/style.css" });
    +import { buildModuleFileUrl } from "@jahia/javascript-modules-library";
    +const url = buildModuleFileUrl("dist/style.css");

    Make sure the path is made available in package.json > jahia > static-resources.

    Path is no longer resolved from <module>/static, but from <module>. You may change the module with buildModuleFileUrl("dist/style.css", { moduleName: "other-module" }).

  • To get the URL of a Jahia endpoint:

    -import { buildUrl } from "@jahia/javascript-modules-library";
    -const liveUrl = buildUrl({ value: renderContext.getURLGenerator().getLive() }, renderContext, currentResource);
    +import { buildEndpointUrl } from "@jahia/javascript-modules-library";
    +const liveUrl = buildEndpointUrl(renderContext.getURLGenerator().getLive());

editable was changed to readOnly (#187)

In <Render> and <Area>, use readOnly instead of editable={false} to prevent the children from being editable.

limitedAbsoluteAreaEdit={true} is now readOnly="children".

getNodeFromPathOrId was removed (#189)

Use session.getNode(<path>) and session.getNodeByIdentifier(<id>) instead.

Changed <Area> and <AbsoluteArea> parameters (#199)

  • Replaced path and level parameters of <AbsoluteArea> with parent, which expects a JCR node.
  • Removed path and areaAsSubNode of <Area>, use <AbsoluteArea parent={currentNode/session.getNode(path)} /> instead.

Some arguments have been renamed: areaView -> view, allowedTypes -> allowedNodeTypes, areaType -> nodeType.

New features

Added getSiteLocales() (#189)

This function produces a record (JS plain object), whose keys are language codes (e.g. en_US), mapped to a locale. Building a language-switcher should be easier and less error-prone with this new API:

<ul>
  {Object.entries(getSiteLocales()).map(([language, locale]) => (
    <li key={language}>
      <a
        href={buildNodeUrl(mainNode, { language })}
        aria-current={language === currentResource.getLocale().toString() ? "page" : undefined}
      >
        {locale.getDisplayLanguage(locale)}
      </a>
    </li>
  ))}
</ul>

Added <RenderChild> and <RenderChildren> (#190)

These two components make rendering respectively a single child node, many children nodes easier and less verbose.

-{currentNode.hasNode(name) ? <Render node={currentNode.getNode(name}} : <AddContentButtons />}
+<RenderChild name={name} />
-{getChildNodes(currentNode, -1).map((node) => (
-  <Render key={node.getIdentifier()} node={node} />
-))}
-<AddContentButtons />
+<RenderChildren />

Added priority to jahiaComponent (#213)

The first argument of jahiaComponent now accepts an additional setting: priority. This will come in handy when you have views or templates for mixins and you want to make sure the right one is rendered when several can be rendered.

jahiaComponent(
  {
    componentType: "view",
    nodeType: "nsmix:mixin",
    priority: 10, // Non-default priority value (default is 0), this view will be picked if no higher priority view matches a node
  },
  () => <p>Render me!</p>,
);

It's an integer working roughly like CSS z-index: the biggest integer wins. You can also use an negative integer to create a "fallback" view or template, that is, a view or template only used if there is no better match. The default value is 0.

Windows is now officially supported (#196)

You should now be able to develop JavaScript Modules in Windows without any issues. If that's not the case, please reach out to us.

Deprecations

  • buildNavMenu is now deprecated and will be removed in the future. This function has complexity and performance issues, and is too complex for simple needs, too simple for complex needs. We now recommend you build your navigation menu by iterating over JCR nodes.

Full Changelog: 0_5_6...0_6_0

JavaScript Modules v0.5.6

10 Mar 14:46

Choose a tag to compare

New features

This release introduces the ability to place <HydrateInBrowser> anywhere in the component tree, not only as a leaf as it used to be. In practice, this means that <HydrateInBrowser> now accepts children, and they'll be rendered server-side!

// default.server.tsx
jahiaComponent(
  {
    componentType: "view",
    nodeType: "example:Component",
    displayName: "Example Component"
  },
  ({ title }: { title: string }) => {
    return (
      <HydrateInBrowser child={HydratedComponent} props={{ title }}>
        <p>I'm rendered on the server</p>
        {/* You can place server-only code here, like <Render> components */}
      </HydrateInBrowser>
    )
  }
);

// HydratedComponent.client.tsx
export default function HydratedComponent({title, children}: { title: string; children: React.ReactNode }) {
  // This component can contain client-only code: useState, useEffect...
  return (
    <article>
      <h1>{title}</h1>
      {/* Server-rendered content will be inserted here: */}
      {children}
    </article>
  )
}

There's one small gotcha with our implementation for now: we insert a <div> element to create a hydration boundary. This a related to a React limitation and we haven't found a way around it yet. If this is an issue for your use cases, please let us know.

If you add children to <RenderInBrowser>, they'll be used as a placeholder until client-side rendering takes over. It can be used like this:

jahiaComponent(
  {
    componentType: "view",
    nodeType: "example:Component",
    displayName: "Example Component"
  },
  ({ place }: { place: string }) => {
    return (
      <RenderInBrowser child={MapComponent} props={{ place }}>
        <p>The map is loading, please wait...</p>
      </RenderInBrowser>
    )
  }
);

We also added support for all export default statements, no only export default function. (#151)

Full Changelog: 0_5_5...0_5_6

JavaScript Modules v0.5.5

07 Mar 09:12

Choose a tag to compare

What's Changed

Other Changes

Full Changelog: 0_5_4...0_5_5

JavaScript Modules v0.5.4 👋

06 Mar 13:13

Choose a tag to compare

Hello World! 👋

We updated the Hello World template (npm init @jahia/module) to mirror our recent changes regarding the build environment: JavaScript Modules v0.5.1 ⚡️

Here is what you should expect after creating a new module:

image

It promotes all the practices we now consider as "best practices":

  • Single folder components (define JSX, CSS and CND in the same folder)
  • CSS modules
  • Internationalized website
  • Typed JSX (TSX)
  • Tooling: Prettier & ESLint

We also fixed a few bugs in @jahia/vite-plugin:

  • Vite should bundle all dependencies in SRR mode in #142
  • Improved treeshaking and simpler client output in #145

Full Changelog: 0_5_3...0_5_4

JavaScript Modules v0.5.3

03 Mar 08:04

Choose a tag to compare

What's Changed

Full Changelog: 0_5_1...0_5_3

JavaScript Modules v0.5.1 ⚡️

26 Feb 16:31

Choose a tag to compare

Welcome Vite! ⚡️

This release is a fairly large release with a major architectural rewrite on our end. This means a lot of breaking changes on your end too (sorry about that) but that's for the best: we replaced Webpack with Vite.

We heard your feedback about Webpack and decided to solve it by removing it altogether. If you're not familiar with Vite (and Webpack btw), it's a bundler: it takes source code in various languages (JS, TS, CSS, SCSS...) and produces a coherent output that the runtime can understand (e.g. JS+CSS for the browser).

All your configuration needs should be handled by a newcomer in this repository: @jahia/vite-plugin. It's a Vite plugin that takes care of everything for you:

import { defineConfig } from 'vite'
import jahia from '@jahia/vite-plugin'

export default defineConfig({
  plugins: [
    // ✨ And voilà!
    jahia()
  ]
})

There's no migration guide to migrate from Webpack to Vite—there's too much to cover—so instead we offer you a migration session with our Developer Advocate, @GauBen: → Book an appointment

Changelog

  • Build your JavaScript Modules with Vite and enjoy all its features out of the box: TypeScript transpilation, CSS Modules, raw imports, CSS preprocessors...
  • @jahia/javascript-modules-library is now written in TypeScript, with slightly stricter types, helping you find bugs before even running your code. As far as you're concerned, it's only a typing library, its runtime is handled by the JavaScript Modules Engine.
  • React 19! We bumped the supported React version and enabled support for the modern JSX transform.
  • The client directory (src/client) no longer needs to be flat, you can nest and organize your components the way you like.
  • Hydration now supports a larger range of objects: your props can be Map, Set, Date objects and more.
  • <AddContentButtons /> now takes a list of node types: <AddContentButtons nodeTypes={['ns:text', 'ns:richText']} />
  • Registering your components is now simpler, we added a jahiaComponent function that takes care of both the declaration (formerly defineJahiaComponent) and the registration (formerly registerJahiaComponents):
    jahiaComponent(
      {
        nodeType: "ns:foobar",
        displayName: "My fancy content type",
        componentType: "view",
      },
      ({ foo, bar }, { currentNode }) => {
        // ^^^ props  ^^^ server context
        return (
          <p>
            {foo} {bar}
            <a href={currentNode.getUrl()}>Read more</a>
          </p>
        );
      },
    );
  • Our Vite plugin supports glob entrypoints, allowing you to get rid of all the export * from ... statements
  • Under the hood, as we completely removed Webpack for both frontend and backend code, we no longer use Webpack Module Federation. Instead, we leverage a standard JS feature: <script type="importmap">. If you want to support old web browsers (see unsupported browsers), you'll have to add es-module-shims to your Jahia instance.

All changes: 0_4_0...0_5_1

javascript-modules-0.4.0

10 Feb 11:04

Choose a tag to compare

What's Changed

Other Changes

New Contributors

Full Changelog: 0_3_0...0_4_0

javascript-modules-0.3.0

23 Jan 15:11

Choose a tag to compare

0_3_0

[skip ci] [maven-release-plugin]copy for tag 0_3_0