Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serving Polymer App to a /path not at root

Tags:

polymer

So the first thing I want to do with a new Polymer app is deploy to a directory on an existing website. The only thing that seems to work is deploying to root /.

Let's take the Shop example. I do:

  1. polymer init and choose shop
  2. polymer build
  3. Robocopy.exe .\build\bundled\ C:\inetpub\wwwroot\p\ /MIR
  4. start http://localhost/p/

You see I'm on Windows. I assume that using IIS is irrelevant, since I'm relying on the server just to serve static content.

What do I need to edit in the shop template to make it work at the url http://localhost/p/?

like image 372
Chris F Carroll Avatar asked Feb 07 '17 12:02

Chris F Carroll


Video Answer


2 Answers

The polymer-cli created apps came with assumption of serving from root level '/'. In generated project index.html you will find two comments

<!--

      The `<base>` tag below is present to support two advanced deployment options:
      1) Differential serving. 2) Serving from a non-root path.
    
      Instead of manually editing the `<base>` tag yourself, you should generally either:
      a) Add a `basePath` property to the build configuration in your `polymer.json`.
      b) Use the `--base-path` command-line option for `polymer build`.
    
      Note: If you intend to serve from a non-root path, see [polymer-root-path] below.

-->
    <base href="/">
<!-- ... -->

<script>
    /**
    * [polymer-root-path]
    *
    * By default, we set `Polymer.rootPath` to the server root path (`/`).
    * Leave this line unchanged if you intend to serve your app from the root
    * path (e.g., with URLs like `my.domain/` and `my.domain/view1`).
    *
    * If you intend to serve your app from a non-root path (e.g., with URLs
    * like `my.domain/my-app/` and `my.domain/my-app/view1`), edit this line
    * to indicate the path from which you'll be serving, including leading
    * and trailing slashes (e.g., `/my-app/`).
    */
    window.Polymer = {rootPath: '/'};
  // ...    
 

</script>

if in this index.html file you comment out base tag and set window.Polymer rootPath to something like '/0/polymer-test/build/es5-bundled/' you will be able to navigate in app on http://localhost/0/polymer-test/build/es5-bundled/

like image 110
Sasha Firsov Avatar answered Oct 02 '22 15:10

Sasha Firsov


The Polymer shop-app assumes it will be deployed on the server root. Therefore it has all of the links and routes hard-coded to that assumption.

This means, that you will have to change all of the following:

  • all absolute links between the pages,
  • all pattern parameters in app-route elements (this is not necessary when useHashAsPath = true),
  • all absolute imports, including the lazy ones via importHref,
  • update the absolute locations within the service worker (use instructions from here) and
  • all references to static content (CSS, images, JS files)

I'm guessing your main goal isn't porting the shop-app, but rather future proofing your own app so that it can also be deployed to non-root locations on the server.

For this, I will mention two ways, depending on which value of useHashAsPath you use for the app-location element. This setting defaults to false, which means that you must use full URLs, instead of the hashbang equivalents.

Scenario 1: useHashAsPath = true

This is the easiest of both approaches, since you simply treat all URLs between the pages as absolute links. For example: <a href="#/tabs/">Tabs</a>.

The next step is to reference all static content and imports via relative links.

The last step is to update your service worker as shown here.

Scenario 2: useHashAsPath = false

If you dislike the hashbang URLs, go for this scenario. As you can figure out, this approach is a bit more difficult, but still manageable (especially when you start from scratch).

Firstly, you should still use absolute links, since relative links between a complex routing scheme can quickly cause problems (e.g. when not all pages are on the same directory level).

But since absolute links are a no-go, you will have to add some additional pre-processing upon build time. The point is to prefix all links with, say __ROOT__, and then replace all of those values with your actual document root. The links would then look like something this:

<a href="__ROOT__/some/page">Some page</a>

And you would use gulp-replace or something similar to replace __ROOT_ with /your-document-root across all of your source files in order to produce something like this:

<a href="/your-document-root/some/page">Some page</a>

At this point, you've got your links fixed. But this is only part of the problem. You must also apply the same fix to all of your app-route elements. For example:

<app-route pattern="__ROOT__/some/page" [...]></app-route> // Other parameters ommited

As with other resources, such as images and CSS files, you can also include them as absolute links and add the __ROOT__ prefix, but I would advise against this and would rather use relative paths.

The last step is to update your service worker as shown here.


Read more about routing: https://www.polymer-project.org/1.0/blog/routing

like image 33
alesc Avatar answered Oct 02 '22 16:10

alesc