Skip to Content
CustomizeRepository UIJavaScript AssetsOverview

JavaScript Assets

NRP repositories support two approaches for client-side interactivity: simple/vanilla JavaScript for lightweight DOM manipulation, and React for complex stateful UI components.

Choosing the Right Approach

All JavaScript in NRP repositories is bundled through Webpack/RSpack (see Webpack Configuration), regardless of whether you use vanilla JS or React. Start with vanilla JavaScript for simple use cases — it’s easier to implement for lightweight interactions. Introduce React when you need state management, component reusability, or any complex interfaces.

ScenarioUse
Simple form validation, toggles, mobile menusVanilla JS
One-off event listeners (click, scroll)Vanilla JS
jQuery plugins or small interactionsVanilla JS
Complex forms with validationReact
State-driven interfaces (filters, tabs)React
Datasets with search/filter/sortReact

File Organization

JavaScript assets are organized within each UI module, typically with a nested folder structure that mirrors the module name under ui/<module>/semantic-ui/js/<module>/:

      • webpack.py
              • index.js
              • index.js
              • filters.js
      • webpack.py
    • Module folders - Each UI module has its own webpack.py and semantic-ui/js/ directory
    • semantic-ui/js/<module>/ - JavaScript folder named after the module

    Quick Start

    Adding Vanilla JavaScript

    1. Create a JS file for your feature in ui/<module>/semantic-ui/js/<module>/:
    // ui/myfeature/semantic-ui/js/myfeature/home-page-search.js document.addEventListener('DOMContentLoaded', () => { const searchInput = document.querySelector('input.form-control'); if (searchInput) { searchInput.addEventListener('keydown', (e) => { if (e.key === 'Enter') { window.location.href = `/search?q=${encodeURIComponent(searchInput.value)}`; } }); } });
    1. Register the entry point in your module’s webpack.py (see Webpack Configuration):
    ui/myfeature/webpack.py
    from invenio_assets.webpack import WebpackThemeBundle theme = WebpackThemeBundle( __name__, ".", default="semantic-ui", themes={ "semantic-ui": dict( entry={ "home-page-search": "./js/myfeature/search/home-page-search.js", # ← Add your entry point here }, ) } )
    1. Include the webpack bundle in your Jinja/JinjaX template:
    templates/homepage.html
    {%- block javascript %} {{ webpack['home-page-search'] }} {%- endblock %}

    Adding a React app

    1. Include a div with your target id in the Jinja or JinjaX template where you want the React app to appear:
    <div id="search-root"></div>
    1. Create your React app in ui/<module>/semantic-ui/js/<module>/:
    // ui/mymodel/semantic-ui/js/mymodel/search/search.js import ReactDOM from "react-dom"; import { SearchApp } from './SearchApp'; document.addEventListener('DOMContentLoaded', () => { const rootElement = document.getElementById('search-root'); if (rootElement) { ReactDOM.render(<SearchApp />, rootElement); } });
    1. Register the entry point in your module’s webpack.py (see Webpack Configuration):
    ui/mymodel/webpack.py
    from invenio_assets.webpack import WebpackThemeBundle theme = WebpackThemeBundle( __name__, ".", default="semantic-ui", themes={ "semantic-ui": dict( entry={ "search": "./js/mymodel/search/search.js", # ← Add your entry point here }, ) } )
    1. Include the webpack bundle in your Jinja/JinjaX template:
    templates/search.html
    {%- block javascript %} {{ webpack['search.js'] }} {%- endblock %}

    The webpack Jinja variable provides access to all bundled JavaScript assets. Use the entry point name (from step 3) with .js appended to include the bundle entry.

    Topics

    Last updated on