https://github.com/gustafnk/h-include
Declarative client-side inclusion for the Web, using Custom Elements V1
https://github.com/gustafnk/h-include
webcomponents
Last synced: 9 months ago
JSON representation
Declarative client-side inclusion for the Web, using Custom Elements V1
- Host: GitHub
- URL: https://github.com/gustafnk/h-include
- Owner: gustafnk
- License: mit
- Created: 2016-04-27T19:58:34.000Z (over 9 years ago)
- Default Branch: main
- Last Pushed: 2024-09-10T20:18:45.000Z (over 1 year ago)
- Last Synced: 2025-03-31T09:03:15.560Z (9 months ago)
- Topics: webcomponents
- Language: HTML
- Homepage: https://gustafnk.github.io/h-include/
- Size: 499 KB
- Stars: 251
- Watchers: 9
- Forks: 18
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# h-include.js
Declarative client-side transclusion, using [Custom Elements V1](https://developers.google.com/web/fundamentals/web-components/customelements). Perfect for [Microfrontend architectures](https://micro-frontends.org/), in combination with server-side transclusion technologies like [Edge-Side Includes](https://en.wikipedia.org/wiki/Edge_Side_Includes).
Based on [hinclude.js](https://github.com/mnot/hinclude) by [@mnot](https://github.com/mnot/).
*Breaking changes in version 4.0.0*:
Rename `alt` attribute to `when-false-src` to support future feature for error handling.
*Breaking changes in version 3.0.0*:
- Because h-include is now using Custom Elements V1, we recommend that you update your polyfill (i.e. [document-register-element](https://github.com/WebReflection/document-register-element)) to the latest version.
- If you have created your own custom elements that inherit from h-include, they too need to be based on Custom Elements V1. See [EXTENDING.md](EXTENDING.md) for an example how to extend h-include.
- The `navigate` attribute is broken out into the separate element ``, located in `lib/h-include-extensions.js`.
- Changes to @src attribute don't automatically refresh an h-include element anymore
## Usage
Include an HTML resource like this:
```
```
Each `` element will create an AJAX request to the URL and replace the `innerHTML` of the element with the response of the request.
See [the demo page](http://gustafnk.github.com/h-include/) for live examples.
## Installation
Install using npm:
```shell
$ npm install h-include
```
## Rendering Mode
By default, each include is fetched in the background and the page is updated only when they all are available.
This is bounded by a timeout, by default 2500 ms. After the timeout,
h-include will show what it has and keep on listening for the remaining responses.
However, it's also possible to have responses from `` elements become visible as they become available, by providing configuration:
```
HIncludeConfig = { mode: 'async' };
```
While this shows the included content quicker, it may be less visually smooth.
## Custom Elements polyfill
You need to use a polyfill for enabling [W3C Custom Elements](http://w3c.github.io/webcomponents/spec/custom/) for browsers not supporting Custom Elements V1.
We recommend using [document-register-element](https://github.com/WebReflection/document-register-element) (5KB minified and gzipped) as the polyfill for [W3C Custom Elements](http://w3c.github.io/webcomponents/spec/custom/).
Example:
```
this.customElements||document.write('<script src="//unpkg.com/document-register-element"><\x2fscript>');
...
```
All extensions inherit h-include's base behavior, when applicable.
To create your own elements that inherit from ``, see [EXTENDING.md](EXTENDING.md).
Example usage, in summary:
| Resource fragments | Content fragments | Example |
|---|---|---|
| ESI | ESI | Short static pages |
| ESI | h-include | Dynamic web app with static content fragments (i.e. search) |
| ESI | ESI + h‑include‑lazy | Pages with *homogeneous* lists, lazy loaded on scroll below the fold |
| ESI + h‑import‑lazy | ESI + h‑include‑lazy | Pages with *heterogeneous* content, lazy loaded on scroll below the fold together with resource fragments |
| h‑import | h‑include (etc) | Sites without access to ESI |
### h-include-lazy
Only includes the HTML resource if the element is about to enter the viewport, by default 400 pixels margin, using the [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) (which needs to be polyfilled).
After page load, elements in the DOM need to registered to the Intersection Observer:
```
window.addEventListener('load', function() {
HInclude.initLazyLoad();
});
```
Example:
```
...
```
Example repo using plain h-include (without lazy) and the Intersection Observer API to pull in content on ‘in-view’ scroll interaction can be found [here](https://github.com/nicolasdelfino/iobserver-h-include).
### h-import
Request an HTML resource and include all found script and stylesheet references.
Example:
```
```
If possible, use [Edge-Side Includes](https://en.wikipedia.org/wiki/Edge_Side_Includes) (or similar) to import statically loaded resource fragments, due to performance reasons.
To load resources, h-import and h-import-lazy call `HInclude.loadResources` with an array of urls to resources. By default, this method delegates the resource loadin to [loadjs](https://github.com/muicss/loadjs), which needs to be on the `window` object. However, `HInclude.loadResources` can be replaced with a loader of your choice.
### h-import-lazy
When lazy loading fragments, it might be the case that additional style and script resources need to be loaded as well. For example, think of a lazy loaded footer with rather specific styling. For these scenarios, use h-import-lazy.
After page load, elements in the DOM need to registered to the Intersection Observer:
```
window.addEventListener('load', function() {
HInclude.initLazyLoad();
});
```
Example:
```
...
```
## h-include-navigate
Use `` to let link navigation events be captured by the element itself, which changes the `src` attribute and triggers a refresh.
Use `target="_top"` to let link inside `h-include` behave as a normal link.
#### Helper function: HInclude.initLazyLoad
By default, the selector for `HInclude.initLazyLoad` is `'h-include-lazy, h-import-lazy'` and the Intersection Observer `rootMargin` and `threshold` default values are `400px 0px` and `0.01` respectively. These can be overridden:
```
HInclude.initLazyLoad('css style selector', {rootMargin: '200px 0', threshold: 0.2});
```
#### Helper function: HInclude.loadResources
Load an array of script and stylesheet resources (to be overridden).
## Advanced usage
### Conditional inclusion using when
When offers a way of using a predicate for inclusion. It also features an optional `when-false-src` attribute that functions as the source of inclusion given that the predicate fails.
```
```
The method specified in the when attribute may be namespaced and needs to return true for the inclusion of the url specified in the src attribute to occur.
### Request errors and alternative inclusion using alt
The alt attribute functions as an alternative source of inclusion should the url result in a request error.
```
```
### Refresh method
Refresh an element by using the `refresh()` method:
```js
const element = document.getElementsByTagName('h-include')[0];
element.refresh();
```
### Media queries
Use media queries to have different fragments for different devices:
```
```
`` will not listen to changes to screen orientation or size.
### Fragment extraction
Include an HTML resource and extract a fragment of the response by using a selector:
```
```
### XMLHttpRequest.withCredentials
Enable [XMLHttpRequest.withCredentials](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials):
```
```
## Configuration
Set buffered include timeout (default is `2500` ms):
```js
HIncludeConfig = { timeout: 10000 };
```
Set include mode to `async` (default is `buffered`):
```js
HIncludeConfig = { mode: 'async' };
```
Throw if caught in an infinite include loop (default is `false`):
```js
HIncludeConfig = { checkRecursion: true };
```
If `checkRecursion` is `true`, h-include will traverse the DOM upwards to find another h-include element with the same src attribute, until the root node. This operation takes a few CPU cycles per h-include, which is why it's not enable by default.
## Error Handling
If fetching the included URL results in a 404 Not Found status code, the class of the include element will be changed to include_404. Likewise, a 500 Server Error status code will result in the include element’s class being changed to include_500.
## Browser support
All modern browsers and IE down to IE10 are supported. If you find something quirky, please file an issue.
## HTTP/2 improves XHR performance
Browsers with HTTP/2 are [using HTTP/2 for xhr requests as well](http://stackoverflow.com/questions/32592258/do-current-xhr-implementations-take-advantage-of-http-2). So, if both the server and the current browser supports HTTP/2, all requests made with h-include will go through the same TCP connection, given that they have the same origin.
## Bundler
### Parcel
With this plugin, Parcel searches and optimizes all h-include tags
[https://github.com/joserochadocarmo/parcel-plugin-h-include](https://github.com/joserochadocarmo/parcel-plugin-h-include)
## FAQ
Please see the [FAQ](FAQ.md) for some frequently asked questions.