stencil-community / stencil-router

A simple router for Stencil apps and sites
https://stenciljs.com/
MIT License
188 stars 55 forks source link

Routes are not working under sub-directory website (host) #43

Open MoAsmar opened 6 years ago

MoAsmar commented 6 years ago

I am working on an app with a few components and trying to put it on my website under a sub-directory:

main component:

import { Component } from '@stencil/core';
import '@stencil/router';

@Component({
  tag: 'hello-stencil-main',
  styleUrl: 'hello-stencil-main.scss'
})
export class HelloStencilMain {

  render() {
    return (
      <div>
        <stencil-router root='/apps/hellostencil'>
          <stencil-route url='/' component='home' exact={true}>
          </stencil-route>
          <stencil-route url='/hello' component='hello' exact={true}>
          </stencil-route>
      </div>
    );
  }
}

stencil.config.js release config:

const sass = require('@stencil/sass');
exports.config = {
  outputTargets: [
    {
      type: 'www',
      dir: 'www',
      baseUrl: '/',
      buildDir: '',
      resourcesUrl: '/app/',
    },
    {
      type: 'www',
      dir: 'release',
      baseUrl: '/apps/hellostencil/',
      buildDir: '',
      resourcesUrl: '/apps/hellostencil/app/'
    }
  ],
  plugins: [
    sass()
  ]
};
exports.devServer = {
  root: 'www',
  watchGlob: '**/**'
};

Index.html

<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
  <meta charset="utf-8">
  <title>Hello Stencil</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0">
  <meta name="theme-color" content="#16161d">
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta http-equiv="x-ua-compatible" content="IE=Edge" />
  <script src="./app.js"></script>
</head>

<body>
  <hello-stencil-main></hello-stencil-main>
</body>

</html>

package.json dependencies

 "dependencies": {
    "@capacitor/cli": "^1.0.0-alpha.35",
    "@capacitor/core": "^1.0.0-alpha.35",
    "@stencil/core": "0.7.24",
    "@stencil/router": "latest",
    "@stencil/sass": "latest",
    "@types/jquery": "^3.3.1",
    "tslib": "^1.9.0"
  },
  "devDependencies": {
    "@stencil/dev-server": "latest",
    "@stencil/utils": "latest",
    "@types/jest": "^21.1.10",
    "jest": "^21.2.1",
    "typescript": "^2.8.3"
  },

After few investigations and failed tries, I figured out how to host my app under a sub-directory by adding 'root' property to and adding baseUrl to the release configs as mentioned above, this makes my home page url works('https://myhost/apps/hellostencil'), but the sub page which is under my sub-directory ('https://myhost/apps/hellostencil/hello') is not working, the component is not being rendered at all, and the stencil route tag is empty! Also adding a <stencil-route-link url='/hello'></stencil-route-link> to my home page as anchor to go to my hello page did not make any difference.

Please help!

Note: removing 'root' tag from stencil-route and testing locally (npm start), everything works perfectly!

marisaoliva commented 6 years ago

any progress? I have the same problem

arby50 commented 6 years ago

Similar issue. While investigating it, I copied your router code:

      <div>
        <stencil-router root='/apps/hellostencil'>
          <stencil-route url='/' component='home' exact={true}>
          </stencil-route>
          <stencil-route url='/hello' component='hello' exact={true}>
          </stencil-route>
      </div>

and duplicated the problem. I removed the <div/>tag:

        <stencil-router root='/apps/hellostencil'>
          <stencil-route url='/' component='home' exact={true}>
          </stencil-route>
          <stencil-route url='/hello' component='hello' exact={true}>
          </stencil-route>

I duplicated this after a 'git clone' of the PWA toolkit. I installed the @stencil/router, added an import for the @stencil/router to my-app.tsx and changed all <ion-router>and <ion-route> to <stencil-router> and <stencil-route>:

      <ion-app>
        <stencil-router>
          <stencil-route url="/" component="app-home" />
          <stencil-route url="/profile/:name" component="app-profile" />
        </stencil-router>
      </ion-app>

and got a blank page.

Following your code above:

      <div>
        <stencil-router>
          <stencil-route url="/" component="app-home" />
          <stencil-route url="/profile/:name" component="app-profile" />
        </stencil-router>
      </div>

I got a blank page.

Removing the <div/>tag allowed the app to display:

  render() {
    return (
      <stencil-router>
        <stencil-route url="/" component="app-home" />
        <stencil-route url="/profile/:name" component="app-profile" />
      </stencil-router>
    );
  }

The app now displays. However, there still is no app navigation. I added a stencil-route-link in addition to the existing ion-button, both attempting to go to /profile/ionic. Neither worked.

MoAsmar commented 6 years ago

Thanks @arby50, I solved this one using root attribute on stencil-router element, but still this router isn't mature enough, I am here to add a bug regarding guards.

marisaoliva commented 6 years ago

thanks @arby50!!

daviddietz commented 5 years ago

Any updates on this issue. I am having the same problem (if I understand it correctly) where my component root (where the main component and router live) is not the root of the application. My navigation only works if the URL resolves from the root of the application, NOT relative to where the component root is located. I thought I could solve it by adding the path to the component root passed down as a prop to each component, but then it doesn't resolve the full path. Here is an example of my router definition.

<stencil-router root={mileOnComponentRoot}>
    <stencil-route
        url='/'
        component="mile-on-trip-list"
        componentProps={componentProps}
        exact={true}
    />
    <stencil-route
        url={'/trips/:tripId/stops/:stopId'}
        component="mile-on-stop"
        componentProps={componentProps}
    />
    <stencil-route
        url={'/trips/:tripId/map'}
        component="mile-on-trip-map"
        componentProps={componentProps}
    />
    <stencil-route
        componentProps={componentProps}
        exact={true}
        routeRender={() => {
        return <h1>Error loading Mile On Trip Planner</h1>;
        }}
    />
</stencil-router>

And my attempt at solving the issue by including the component root when pushing via history.

let url = this.mileOnComponentRoot + `/trips/${this.tmsTripId}/stops/${stopId}`;
this.history.push(url);
ToothpickFactory commented 5 years ago

Any updates? The above solution does work when using the root attribute. The problem with that is that you have to change the root for local dev and production.

FortinFred commented 4 years ago

I think this might be related to: https://github.com/ionic-team/stencil-router/issues/80#issuecomment-582551305

sniederb commented 3 years ago

This works for me:

stencil.conf.js

baseUrl: '/foobar'

main component

<stencil-router root="/foobar/">
  <stencil-route-switch>
    <stencil-route url="/login" component="demo-login"></stencil-route>
    <stencil-route url="/main" component="demo-main"></stencil-route>
  </stencil-route-switch>
</stencil-router>

and then navigating with this.history.push('./main');

With this I can navigate the app on myhost.com/foobar/login or myhost.com/foobar/main resp.

anderson-marques commented 3 years ago

This works for me:

stencil.conf.js

baseUrl: '/foobar'

main component

<stencil-router root="/foobar/">
  <stencil-route-switch>
    <stencil-route url="/login" component="demo-login"></stencil-route>
    <stencil-route url="/main" component="demo-main"></stencil-route>
  </stencil-route-switch>
</stencil-router>

and then navigating with this.history.push('./main');

With this I can navigate the app on myhost.com/foobar/login or myhost.com/foobar/main resp.

Your answer solved my problem. It works! 👍🏽