Search code examples
javascripthtmlcssangularjsweb-component

How to share a header that is HTML/CSS/JS?


I am starting a new project at work, and we have been tasked to create a Universal Header. This means on the different domains/servers we own, our customer-created sites, and third-party sites we will need a very simple way to give this code to people.

This Universal Header will also contain some search functionality, which is slightly relevant to my question. Put simply, it will contain JavaScript to change the action attribute on its <form> element, depending on the dropdown selection, as well as submitting the form.

The way we want the header to work, is that it lives in one location, we were thinking some kind of HTTP Request to get the header. This will maximize the portability of the Universal Header, in our opinion.

The header will need to integrate nicely with WordPress (not a problem), but also with AngularJS, in our discussions, it's a little less certain whether that will be possible. Thus the "slightly relevant" piece of the search functionality.

One of the solutions we talked about was doing it in HTML like this answer, but I've always been a little more skittish about requesting raw HTML over HTTP, and just dumping it into a page, but maybe it's the right way to go, but maybe not? Since we weren't sure, we thought about the JIRA Issue Collector where they basically stream JavaScript to their customer that then builds the issue tracker button, fixed on the side of a page which has some HTML, CSS, and JS in it. The user can then click this button, which opens a form ready for submission. That may be an over simplification, but basically, their JS snippet packages HTML/CSS/JS and submits data to their server.

This is the direction we would love to go with this: having a single file contain all we need. However, I am wondering a few things:

  • What are some patterns to deal with the "flash" of the header? Since it's AJAXed in on page load, the header will be missing then suddenly be there, how could you deal with that usability problem? I was thinking like a Skeleton area where the header would be, then have the JavaScript replace it, but I don't know if that's trite or not.
  • What's a standard way to bundle the creation of HTML, the CSS, and some JavaScript functionality all contained inside a single file (like a JS file), or better to have an HTML file linking to a JS and Stylesheet? I'm just uncertain about the bundling piece. We won't be using Angular or React for this project, but I do have some familiarity with Webpack, which seems like it could do the job, maybe. Even though this project won't be using Angular or React, it will still need to integrate with other frameworks.
  • One thing I'm thinking about is possibly breaking the HTML into a separate HTTP Request, and having the JavaScript and Styles bundled in another HTTP Request -- almost like a web component. In other words, we could request the HTML, and the CSS/JS in parallel and when it returns, just smash it together in the UI. What are some dangers of doing that, or some things to think about when doing it like that?
  • What would be a good way to integrate this with AngularJS? Since this header will have search functionality in it, we need some way of broadcasting (to AngularJS) when someone submits a search, and what that search is they've submitted.

Originally, for the last point above, I was thinking of attaching it to a window object. Then creating a custom event handler in JavaScript — but how do you do that? Maybe the below pseudo code is way off base, but that's why I'm asking the question:

/// inside the SearchController in AngularJS
$scope.defaultRealm = 'products';

/// to select default realm
document.when('angularJSLoads', function () {
    document.getElementById('universial-header').find('.dropdown', function () {
        // put actions to select $scope.defaultRealm in the dropdown options.
    })
})

/// to search in own defaultRealm
document.querySelector('.dropdown').onEvent('headerSearch', function (e) {
    e.preventDefault();
    var data = event.target.value;

    // do searching in AngularJS
})

If there are some better, cleaner ways, I'd be glad to hear about it.

I appreciate any help with this. This is new territory for us, and overall, we want to be able to have a highly maintainable header that can be easily shared with different domains, etc.


Solution

  • Personally this is how I would handle it.

    I would create on all the page where the header will load, a container that it is planned to load into. That container should have some sort of background indicating its not loaded (typically this is grey, but your UX case may be different)

    Then, to actually deliver your header, build it with JS.

    Create one JS file (say buildHeader.js) and that has code that writes your html, writes a request to your css, and writes a request for your additional js.