diff --git a/src/index.js b/src/index.js
index c50e6068..9128f06c 100644
--- a/src/index.js
+++ b/src/index.js
@@ -151,7 +151,7 @@ class Router extends Component {
this.state = {
url: props.url || getCurrentUrl()
};
-
+
initEventListeners();
}
@@ -179,7 +179,12 @@ class Router extends Component {
}
componentWillMount() {
- ROUTERS.push(this);
+ // preact-render-to-string does not initialize the "next state" field for components.
+ // We can use this to detect a static rendering environment and disable subscriptions.
+ this._ssr = !('_nextState' in this || '__s' in this);
+ if (!this._ssr) {
+ ROUTERS.push(this);
+ }
this.updating = true;
}
@@ -194,7 +199,7 @@ class Router extends Component {
componentWillUnmount() {
if (typeof this.unlisten==='function') this.unlisten();
- ROUTERS.splice(ROUTERS.indexOf(this), 1);
+ ROUTERS.splice(ROUTERS.indexOf(this) >>> 0, 1);
}
componentWillUpdate() {
@@ -230,7 +235,7 @@ class Router extends Component {
let current = active[0] || null;
let previous = this.previousUrl;
- if (url!==previous) {
+ if (!this._ssr && url!==previous) {
this.previousUrl = url;
if (typeof onChange==='function') {
onChange({
diff --git a/test/index.js b/test/index.js
index a63492be..319ccb71 100644
--- a/test/index.js
+++ b/test/index.js
@@ -4,6 +4,14 @@ import assertCloneOf from '../test_helpers/assert-clone-of';
chai.use(assertCloneOf);
+function createBrowserRouter(props) {
+ const router = new Router(props);
+ router.__s = router.state || {}; // _nextState
+ router.__d = true; // _dirty
+ router.componentWillMount();
+ return router;
+}
+
describe('preact-router', () => {
it('should export Router, Link and route', () => {
expect(Router).to.be.a('function');
@@ -13,7 +21,7 @@ describe('preact-router', () => {
describe('Router', () => {
it('should filter children based on URL', () => {
- let router = new Router({});
+ let router = createBrowserRouter({});
let children = [
,
,
@@ -34,7 +42,7 @@ describe('preact-router', () => {
});
it('should support nested parameterized routes', () => {
- let router = new Router({});
+ let router = createBrowserRouter({});
let children = [
,
,
@@ -55,7 +63,7 @@ describe('preact-router', () => {
});
it('should support default routes', () => {
- let router = new Router({});
+ let router = createBrowserRouter({});
let children = [
,
,
@@ -76,7 +84,7 @@ describe('preact-router', () => {
});
it('should support initial route prop', () => {
- let router = new Router({ url:'/foo' });
+ let router = createBrowserRouter({ url:'/foo' });
let children = [
,
,
@@ -87,14 +95,14 @@ describe('preact-router', () => {
router.render({ children }, router.state)
).to.be.cloneOf(children[2]);
- expect(new Router({})).to.have.deep.property('state.url', location.pathname + (location.search || ''));
+ expect(createBrowserRouter({})).to.have.deep.property('state.url', location.pathname + (location.search || ''));
});
it('should support custom history', () => {
let push = sinon.spy();
let replace = sinon.spy();
let getCurrentLocation = sinon.spy(() => ({pathname: '/initial'}));
- let router = new Router({
+ let router = createBrowserRouter({
history: { push, replace, getCurrentLocation },
children: [
,
@@ -123,7 +131,7 @@ describe('preact-router', () => {
let router;
before( () => {
- router = new Router({
+ router = createBrowserRouter({
url: '/foo',
children: [
,