How to accept backbone route which starts with #someNumber - backbone.js

I wanted to allow any routes which start with # and any number
Example :
http://127.0.0.1/mypage/#435fsdfd
This should basically execute renderMyPage.
Tried below things but didn't work
routes : {
"" : "renderMyPage",
"#:/" : "renderMyPage"
}

A few things:
If your application is not being served from the root url / of your domain, you need to tell History where the root really is
Backbone.history.start({root: "/mypage/"});
you don't need to define the hash in the routes, if you just want to match 'something' on the hash this is enough:
routes : {
"" : "renderMyPage",
":value" : "renderMyPage"
},
renderMyPage: function (value) {
}
in the latest backbone (0.9.10) you can use optional arguments so you can do everything in one route
routes : {
"(:value)" : "renderMyPage"
},

Related

Gatsby V4: How to implement gatsby-plugin-react-i18next for client only routes

I'm trying to implement client routes in Gatsby together with gatsby-plugin-react-i18next for two languages. I followed officel Gataby documentation and there is no client only path implementation explained.
Below is the code i implemeted.
gatsby-node.js
function langPrefix(page) {
return page.context.language === page.context.i18n.defaultLanguage &&
!page.context.i18n.generateDefaultLanguagePage
? ''
: `/${page.context.language}`
}
exports.onCreatePage = ({ page, actions }) => {
const { createPage } = actions
// Removing the ^ skips an optional /:lang prefix
if (page.path.match(/\/app/)) {
// adding lang if it's not the default page.
page.matchPath = `${langPrefix(page)}/app/*`
createPage(page)
}
}
Appjs
src/app/app.js
function App() {
return (
<>
<Router basepath="/:lang/app">
<PrivateRoute path="/accounthome" component={AccountHome} location=""/>
</Router>
<Router basepath="/app">
<PrivateRoute path="/accounthome" component={AccountHome} location=""/>
</Router>
</>)
}
export default App
Gatsby config
{
resolve: `gatsby-plugin-react-i18next`,
options: {
localeJsonSourceName: `locale`, // name given to `gatsby-source-filesystem` plugin.
languages: ["en", "fr"],
defaultLanguage: `en-us`,
fallbackLanguage: `en-us`,
// if you are using Helmet, you must include siteUrl, and make sure you add http:https
siteUrl: `https://my.costco.com/`,
ns: langTranslationConfig,
// you can pass any i18next options
i18nextOptions: {
interpolation: {
escapeValue: false // not needed for react as it escapes by default
},
nsSeparator: false
},
pages: [
{
matchPath: '/:lang/app/accounthome',
getLanguageFromPath: true,
excludeLanguages: ['en-ca']
},
{
matchPath: '/preview',
languages: ['en']
}
]
}
}
Router path : http://localhost:8000/en-us/app/accounthome
When am accessing this rote in browser This code show Gatsby.js development 404 page not found. Any pointer what am missing and am not sure how to access the translation contents in client only route page example account home page. Do i need to write the graph query in account home page or i dont need to ?
I think your regex is leaking your code. I guess it should look like:
if (page.path.match(/^\/app/)) {
page.matchPath = `${langPrefix(page)}/app/*`
createPage(page)
}
Either way, check the created page list by accessing the 404 page in development mode. By default, there should be a list of all created pages. Check the paths there to see if you can spot any mistakes or trailing slash issues.
The problem here is that your page is not being generated properly, that's why it throws a 404, so checking the created pages may help you to spot the mistake or at least, a thread to pull.
After a few research I've seen that you are basing your approach in: Gatsby can't find client routes when using gatsby-plugin-react-i18next
In their case, the langPrefix function is only prefixing the language to the page slug if it's the default one:
function langPrefix(page) {
return page.context.language === page.context.i18n.defaultLanguage &&
!page.context.i18n.generateDefaultLanguagePage
? ''
: `/${page.context.language}`
}
In your case, I'm not sure the plugin supports en-us (it's en-US according to https://github.com/microapps/gatsby-plugin-react-i18next/issues/100) and I think that's the reason why there's a leak in your page creation. Try using en instead of en-us or directly looking for en-US paths.

Cannot use gatsby-plugin-intl for single page site

I'm using Gatsby and I want build a single page site, so without create pages. For achieve this I edited gatsby-node.js with the following code:
exports.onCreatePage = async ({ page, actions }) => {
const { createPage } = actions
if (page.path === "/") {
page.matchPath = "/*"
createPage(page)
}
}
in that case, each request is re-routed to the index.js page, which is the only one.
Then, in the index.js page I have:
const IndexPage = () => {
const intl = useIntl()
const locale = intl.locale
return (
<BGTState>
<BlogState>
<Layout>
<Router>
<Home path={`${locale}/`} />
<Section path={`${locale}/:sectionSlug`} />
<Collection path={`${locale}/:sectionSlug/:collectionSlug`} />
<Season
path={`${locale}/:categorySlug/:collectionSlug/:seasonSlug`}
/>
<Product
path={`${locale}/:categorySlug/:collectionSlug/:seasonSlug/:prodSlug`}
/>
<Blog path={`${locale}/blog`} />
<Article path={`${locale}/blog/:articleSlug`} />
<NotFound default />
</Router>
</Layout>
</BlogState>
</BGTState>
)
}
as you can see, I have different routers that load a specific component based on the url.
I have prefixed each path with the current locale to match the correct path.
This mechanism is working fine for the home page only, but for the other links doesn't work. Infact, if I visit something like:
http://localhost:3001/en/category-home/prod-foo
which must load the Collection component, the site simply redirect to:
http://localhost:3001/en
and display the Home component again.
What I did wrong?
UPDATE
Page Structure:
As you can see I have just the index.js which handle all requests as I configured in the gatby-node.js.
If I remove the localization plugin, at least using this configuration:
{
resolve: `gatsby-plugin-intl`,
options: {
// Directory with the strings JSON
path: `${__dirname}/src/languages`,
// Supported languages
languages: ["it", "en", "ci", "fr"],
// Default site language
defaultLanguage: `it`,
// Redirects to `it` in the route `/`
//redirect: true,
// Redirect SEO component
redirectComponent: require.resolve(
`${__dirname}/src/components/redirect.js`
),
},
},
and I don't prefix the url with intl.locale, everything is working fine. But adding redirect: true in the plugin configuration, and prefixing the link with the locale, the site redirect me to the home component.
If you are creating a SPA (Single Page Application, notice the single) you won't have any created pages but index. You are trying yo access to a /category page that's not created because of:
if (page.path === "/") {
page.matchPath = "/*"
createPage(page)
}
That's why your routes don't work (or in other words, only the home page works).
Adapt the previous condition to your needs to allow creating more pages based on your requirements.
I'm using Gatsby and I want build a single page site, so without
create pages. For achieve this I edited gatsby-node.js with the
following code:
It's a non-sense trying to build a SPA application with Gatsby (without creating pages) but then complaining because there's not collection page created.
Make sure that you understand what you are doing, it seems clearly that you need to create dynamically pages for each collection, season, and product so your approach to create SPA won't work for your use-case.
It's possible to keep just index.js without overcomplicating thing? I
just want to understand why my code isn't working 'cause I've passed
the correct url... Removing the localization Gatsby works, so I
suspect there is a localization problem
The only way that http://localhost:3001/category-home/prod-foo (removing the localization) could be resolved is by creating a folder structure such /pages/category-home/prod-foo.js (since Gatsby extrapolates the folder structure as URLs), so, if you want to use localization using your approach, add a structure such en/pages/category-home/prod-foo.js and es/pages/category-home/prod-foo.js (or the whatever locale), and so on. In my opinion, this is overcomplexitying stuff since, for every category, you'll need to create 2 (even more depending on the locales) files.
Gatsby allows you to create dynamic pages and interpolate the locale automatically using built-in plugins on the process, creating each file for the specifically defined locales.

How to use Dynamic Routing to trigger the same .js in pages?

I have multiple routes for e.g:
/solutions/
/solutions/web-development/
/features/
/features/flexbox/
/plugins/
/plugins/permalink/
and so on.
I would like to run the same file (abc.js) for all of these routes. I have checked the Dynamic Routing Section of Next.js but according to that section, My understanding is that I need to create multiple directories and copy the same file on multiple instances.
Is there any way by which I can run the single file for all the DEFINED routes or for the whole site?
EDIT: I know that there is a way to do that by creating Custom Server and manually add dynamic routes BUT I am looking to achieve this without the creation of the external server.
I have found a way to tackle this thing. This can be done using the next.config.js file. The only thing which you needed is the page URLs and then you can apply the same file or even add conditions to apply using multiple files.
Here is the sample code:
module.exports = {
exportPathMap: async function(
defaultPathMap,
{ dev, dir, outDir, distDir, buildId }
) {
const paths = {};
const pageURLs = [
'/solutions/',
'/solutions/web-development/',
'/features/',
'/features/flexbox/',
'/plugins/',
'/plugins/permalink/'
];
var loopInit = 0;
var loopCount = pageURLs.length;
var url = '';
for (loopInit = 0; loopInit < loopCount; loopInit += 1) {
url = pageURLs[loopInit];
switch(url) {
case '/solutions/':
paths[`${url}`] = {
page: '/solutions',
query: {
slug: url
}
};
break;
case '/features/':
paths[`${url}`] = {
page: '/features',
query: {
slug: url
}
};
break;
default:
paths[`${url}`] = {
page: '/',
query: {
slug: url
}
};
break;
}
}
return paths;
},
exportTrailingSlash: true
};
In the above example, I have hardcoded the URLs in pageURLs variable. You can pass dynamic values in it like get Permalinks from WordPress, URL Alias from Drupal or from any other CMS or Headless CMS, etc.
In the switch case, I am applying different templates on /solutions/ and /features/. For the remaining URLs, I am applying a single template.
NOTE: page: '/' refers index.js under pages directory similarly, page: '/solutions' refers solutions.js under pages directory and so on. It can be changed/vary as per developer choice.
I have tested this solution on the 9.1.4 version of Next.js. Please refer to the Next.js documentation for further details.
https://nextjs.org/docs#custom-configuration
https://nextjs.org/docs#usage
EDITED: This solution works for both server-side rendering and Next.js export.

How to remove routes added by other vendormodules in SilverStripe 4?

I have installed the Blog module for SilverStripe 4, but do not want all the different routes that it has available.
I want to remove for instance the "profile", "archive" and "tag" routes. Those routes are defined by the module's BlogController class.
How can I ensure these are replaced with a HTTP 404 response?
Within your_module_folder/_config/config.yml_if you indicate it should be processed After the blog module and you define those routes it should overwrite them:
---
name: your_module
After:
- 'blog/*'
---
SilverStripe\Control\Director:
rules:
'profile/': 'MyCustomController'
'archive/': 'MyCustomController'
'tag/': 'MyCustomController'
Please review the routing documentation
The controller should only have one action that throws a 404 http error.
use SilverStripe\Control\Director;
use SilverStripe\View\Requirements;
class MyCustomController extends Controller {
private static $allowed_actions = ['index'];
public function index(HTTPRequest $request) {
return $this->httpError(404, "Not Found");
}
}

Vue-router redirect on page not found (404)

I'm trying to redirect to 404.html on page not found using the router.beforeEach global hook, without much success (using Vueand Vue-Router 1.0):
router.beforeEach(function (transition) {
if (transition.to.path === '/*') {
window.location.href = '/404.html'
} else {
transition.next()
}
});
This is not redirecting to page 404.html when a non-existing route is inserted, just giving me an empty fragment. Only when hard-coding some-site.com/* will it redirect to the expected some-site.com/404.html
I'm sure there's something very obvious here that I'm overlooking, but I cannot figure out what.
Please note that what I am looking for is a redirect to a new page, not a redirect to another route, which could be easily achieved by using router.redirect such as in these snippets:
router.redirect({
'*': '404'
})
Whereas on my router.map, I could have the following:
router.map({
'/404': {
name: '404'
component: {
template: '<p>Page Not Found</p>'
}
}
})
I think you should be able to use a default route handler and redirect from there to a page outside the app, as detailed below:
const ROUTER_INSTANCE = new VueRouter({
mode: "history",
routes: [
{ path: "/", component: HomeComponent },
// ... other routes ...
// and finally the default route, when none of the above matches:
{ path: "*", component: PageNotFound }
]
})
In the above PageNotFound component definition, you can specify the actual redirect, that will take you out of the app entirely:
Vue.component("page-not-found", {
template: "",
created: function() {
// Redirect outside the app using plain old javascript
window.location.href = "/my-new-404-page.html";
}
}
You may do it either on created hook as shown above, or mounted hook also.
Please note:
I have not verified the above. You need to build a production version of app, ensure that the above redirect happens. You cannot test this in vue-cli as it requires server side handling.
Usually in single page apps, server sends out the same index.html along with app scripts for all route requests, especially if you have set <base href="/">. This will fail for your /404-page.html unless your server treats it as a special case and serves the static page.
Let me know if it works!
Update for Vue 3 onward:
You'll need to replace the '*' path property with '/:pathMatch(.*)*' if you're using Vue 3 as the old catch-all path of '*' is no longer supported. The route would then look something like this:
{ path: '/:pathMatch(.*)*', component: PathNotFound },
See the docs for more info on this update.
#mani's response is now slightly outdated as using catch-all '*' routes is no longer supported when using Vue 3 onward. If this is no longer working for you, try replacing the old catch-all path with
{ path: '/:pathMatch(.*)*', component: PathNotFound },
Essentially, you should be able to replace the '*' path with '/:pathMatch(.*)*' and be good to go!
Reason: Vue Router doesn't use path-to-regexp anymore, instead it implements its own parsing system that allows route ranking and enables dynamic routing. Since we usually add one single catch-all route per project, there is no big benefit in supporting a special syntax for *.
(from https://next.router.vuejs.org/guide/migration/#removed-star-or-catch-all-routes)
This answer may come a bit late but I have found an acceptable solution. My approach is a bit similar to #Mani one but I think mine is a bit more easy to understand.
Putting it into global hook and into the component itself are not ideal, global hook checks every request so you will need to write a lot of conditions to check if it should be 404 and window.location.href in the component creation is too late as the request has gone into the component already and then you take it out.
What I did is to have a dedicated url for 404 pages and have a path * that for everything that not found.
{ path: '/:locale/404', name: 'notFound', component: () => import('pages/Error404.vue') },
{ path: '/:locale/*',
beforeEnter (to) {
window.location = `/${to.params.locale}/404`
}
}
You can ignore the :locale as my site is using i18n so that I can make sure the 404 page is using the right language.
On the side note, I want to make sure my 404 page is returning httpheader 404 status code instead of 200 when page is not found. The solution above would just send you to a 404 page but you are still getting 200 status code.
To do this, I have my nginx rule to return 404 status code on location /:locale/404
server {
listen 80;
server_name localhost;
error_page 404 /index.html;
location ~ ^/.*/404$ {
root /usr/share/nginx/html;
internal;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ #rewrites;
}
location #rewrites {
rewrite ^(.+)$ /index.html last;
}
location = /50x.html {
root /usr/share/nginx/html;
}
}
Do not use redirect; use beforeEnter
const router = [
// { path: '*', redirect: '/404'},
{ path: '*', beforeEnter: (to, from, next) => { next('/404') } },
{
path: '/404',
name: '404',
component: () => import('#/views/404')
}
]
I do not specifically answer your question, but I have an answer for anyone who is looking for page not found route syntax in Vue js just like I was looking for and came here.
Here are two things you can do:
First, create a component in the views and write some HTML like error 404!
Then import that component in index.js in router folder and import it there like:
import yourcomponentName from '../views/yourcomponentName.vue'
const routes = [
{
path: '/:catchAll(.*)', ->This is the regex pattern
name: 'whatever name you want to give',
component: yourComponentName
}]
If it does not work then use this
const routes = [
{
path: '/:pathMatch(.*)', ->This is the regex pattern
name: 'whatever name you want to give',
component: yourComponentName
}]
Remove the comment: 'This is the regex pattern it is writtern for understanding'
path: "*" is outdated. It belongs to vue-router2 on vue-router3. You can catch all 404 error pages by using
/:pathMatch(.*)*
It works well.
This will make it work too:
{
path: '/*/',
name: 'PageNotFound',
component: () => import('../views/PageNotFound.vue')
}

Resources