matthewp / ocean

Web component server-side rendering

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Relative paths for polyfill and element loading

matthewp opened this issue · comments

Currently the polyfill is added via an absolute URL (per the docs), as are any elements. If your site is hosted on a subpath from the domain like http://example.com/site you need to add /site as a prefix to any of these URLs. This can be cumbersome because often in development you are not using that prefix.

I usually try to make my URLs relative for this reason. It would be nice if Ocean could make these links relative to the current page. Here's an idea for maybe how that could happen (this is using a service worker API, but could work in Deno as well):

import 'https://cdn.spooky.click/ocean/1.0.0/shim.js?global';
import { Ocean } from 'https://cdn.spooky.click/ocean/1.0.0/mod.js';

let { elements, wrap } = new Ocean({ document });

elements.add('my-element', '/elements/my-element.js');

addEventListener('fetch', event => {
  let html = wrap(event.request.url);

  let iter = html`
    <!doctype html>
    <html lang="en">
    <title>My app</title>
    <my-element ocean-hydrate="idle"></my-element>
  `;
});

In the above a relative link will be added for this script.

cc @lamplightdev if you have any opinions/ideas on this.

Could a urlRoot be passed as a new entry in OceanOptions instead, rather than having to manually wrap html?

The issue there is you'd have to create a new instance of Ocean for every request and template compilation is cached in the ocean instances, so you'd lose all of that cached work.

I was thinking more along the lines of keeping the absolute urls, but just prefixing them with the option, e.g. /test, that would work across requests, but I see now that you'd rather keep them relative. In your example how would you work out the different relative paths for say, http://example.com/site/foo and http://example.com/site/foo/bar?

Yeah, this issue is to keep them relative. If there's a prefix you need you can always just add that to your polyfillURL and each element's path.

I'm now leaning towards relativeTo as the name. I tried coming up with shorter names but I think it makes sense to be explicit. Ocean's intended to be a somewhat low-level library anyways that you build high-level ideas on top of.

let{ relativeTo } = new Ocean({ document, polyfillURL: '/scripts/dc-polyfill.js' });

async function homepage(request) {
  let html = relativeTo(request.url);
  html` ... `
}

I've started working on this a little bit.

PR ready in #36