{"action":"created","issue":{"url":"https://api.github.com/repos/Automattic/wp-calypso/issues/3453","repository_url":"https://api.github.com/repos/Automattic/wp-calypso","labels_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/3453/labels{/name}","comments_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/3453/comments","events_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/3453/events","html_url":"https://github.com/Automattic/wp-calypso/pull/3453","id":135386065,"number":3453,"title":"Add 404 universal page for partial matched routes","user":{"login":"lamosty","id":4988512,"avatar_url":"https://avatars.githubusercontent.com/u/4988512?v=3","gravatar_id":"","url":"https://api.github.com/users/lamosty","html_url":"https://github.com/lamosty","followers_url":"https://api.github.com/users/lamosty/followers","following_url":"https://api.github.com/users/lamosty/following{/other_user}","gists_url":"https://api.github.com/users/lamosty/gists{/gist_id}","starred_url":"https://api.github.com/users/lamosty/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lamosty/subscriptions","organizations_url":"https://api.github.com/users/lamosty/orgs","repos_url":"https://api.github.com/users/lamosty/repos","events_url":"https://api.github.com/users/lamosty/events{/privacy}","received_events_url":"https://api.github.com/users/lamosty/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/Automattic/wp-calypso/labels/Framework","name":"Framework","color":"006b75"},{"url":"https://api.github.com/repos/Automattic/wp-calypso/labels/[Status]%20Needs%20Review","name":"[Status] Needs Review","color":"fbca04"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":14,"created_at":"2016-02-22T11:06:30Z","updated_at":"2016-02-25T17:37:24Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/Automattic/wp-calypso/pulls/3453","html_url":"https://github.com/Automattic/wp-calypso/pull/3453","diff_url":"https://github.com/Automattic/wp-calypso/pull/3453.diff","patch_url":"https://github.com/Automattic/wp-calypso/pull/3453.patch"},"body":"Fixes #1135. \r\n\r\nCreate a new React component (`Page-404`) which renders the \"Page not found\" text. Template for this page originates in `server/pages/404.jade`. Render this component when a partially correct route is matched.\r\n\r\nI'm not sure if this is the right approach to handle the 404 page cases for partially matched routes and would like to start a conversation. For more background, please read the #1135 issue.\r\n\r\n## Edit: More info\r\n\r\nOn WP.com, if you go to an URL that is matches neither any Calypso section or is any other valid URL, WP.com's 404 page is shown (i.e. https://wordpress.com/gibberish). It's because (I was told, don't have access) there is some Nginx whitelist of URLs which simply get passed to Calypso, others to non-Calypso sites and the rest is 404.\r\n\r\nHowever, when the URL is partially correct (e.g. `/stats123`), Nginx redirects it to Calypso, which handles it with its router (`page()` calls). There was no 404 route handler so far in Calypso. This PR creates one.\r\n\r\nOne approach to detecting whether the request results in 404 (which I use here) is to add a `page( '*' )` route after all the other routes, so that when the requests gets as far as to this last route handler, we have 404 situation. But all the sections are loaded, even though we only display 404 (wasting CPU). However, this is not a big issue if code-splitting is enabled, which, by default, is.\r\n\r\nThe other approach I was thinking about is to match all the valid URLs even before loading sections. We could simply test for all the sections paths, whether the request's URL (pathname) contains them and if not, display 404. But when code-splitting is enabled, this approach is not much faster than the first one and is additional work, so I'm not sure about going this way.\r\n\r\n## Return 404 right from the server\r\n\r\nCode in this PR handles 404 requests only on the client. If we want to respond to an invalid request directly from server, we need to write code for it on the server. Is it necessary? I can do it but I'm not sure if I should.\r\n\r\n## Testing\r\n\r\n1. Checkout `add/404-universal-page-for-partial-matched-routes` branch and start Calypso server.\r\n2. Go to a non-existent route, starting with existing path to a section. (e.g. `/stats123`).\r\n3. You should be presented with a \"Page not found\" text.\r\n\r\n- [ ] Needs review if this approach is fine\r\n- [ ] Code review\r\n\r\ncc @nb"},"comment":{"url":"https://api.github.com/repos/Automattic/wp-calypso/issues/comments/188896248","html_url":"https://github.com/Automattic/wp-calypso/pull/3453#issuecomment-188896248","issue_url":"https://api.github.com/repos/Automattic/wp-calypso/issues/3453","id":188896248,"user":{"login":"mcsf","id":150562,"avatar_url":"https://avatars.githubusercontent.com/u/150562?v=3","gravatar_id":"","url":"https://api.github.com/users/mcsf","html_url":"https://github.com/mcsf","followers_url":"https://api.github.com/users/mcsf/followers","following_url":"https://api.github.com/users/mcsf/following{/other_user}","gists_url":"https://api.github.com/users/mcsf/gists{/gist_id}","starred_url":"https://api.github.com/users/mcsf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mcsf/subscriptions","organizations_url":"https://api.github.com/users/mcsf/orgs","repos_url":"https://api.github.com/users/mcsf/repos","events_url":"https://api.github.com/users/mcsf/events{/privacy}","received_events_url":"https://api.github.com/users/mcsf/received_events","type":"User","site_admin":false},"created_at":"2016-02-25T17:37:24Z","updated_at":"2016-02-25T17:37:24Z","body":"> But as soon as I try to redirect back to home page.redirect('/'), it doesn't work, because the me section's 404 handler is called before the reader's section routes (/ refers to reader section) and displays the 404, terminating the request. Here's how the page() are added:\r\n\r\n@lamosty from what I can see, this can be avoided like so:\r\n\r\n```js\r\n'if ( ! _loadedSections[ ' + JSON.stringify( module ) + ' ] ) {',\r\n'\trequire( ' + JSON.stringify( module ) + ' )();',\r\n'\t_loadedSections[ ' + JSON.stringify( module ) + ' ] = true;',\r\n'\tpage( ' + path + ', show404 );',\r\n```"}}