I create a dynamic route pages/post/[postname].tsx . and when I send name to the dynamic route the url shows name with url-encode (%20,%E2,...)
I want to show name of the url with dash between words. like below url
https://stackoverflow.com/questions/68041539/using-dash-in-the-dynamic-route-name-in-nuxt-js
how can I do this?
I've used the getStaticPaths method and pass it an object of slugs before. This has worked for me when dealing with a headless CMS'.
export async function getStaticPaths() {
// Hit API to get posts as JSON
const posts = await getPosts()
// Map a new object with just the slugs
const paths = posts.map((post) => {
return { params: { slug: post.slug } }
})
// Return paths
return {
paths: paths,
fallback: true
}
}
I think I understand the problem, you're trying to use a set of strings with spaces e.g "the fundamentals of starting web development" as path param to achieve something like this https://www.geniushawlah.xyz/the-fundamentals-of-starting-web-development. That will most likely convert your spaces to %20 which is normal. I would have advised you to first use replace() method to change all spaces to hyphen before passing it as param but the replace() method only changes the first space and leave the rest. There are other ways to get rid of the spaces programmatically but may be stressful and not worth it, so I'll advise you use an hyphenated set of strings by default.
If not, try to use a for-loop with the replace() method to change all spaces to hyphens, then pass it as param.
Related
I would like to target only the page which does not have specific query param. Value does not matter, what matter is that the params is not in the url, and only then run the experiment.
I tried to use matches regex but does not work:
Regex I use: ^[a-zA-Z]+
It can be done using custom JS func variable like this
function () {
return window.location.search.includes('nameOfYourParam')
}
I am trying to implement redux-query-sync but the url keeps going to default state if I share the url which has the updated state.
https://github.com/Treora/redux-query-sync/blob/master/src/redux-query-sync.js
I have implemented as shown in the sample - https://codesandbox.io/s/url-query-sync-qjt5f?from-embed=&file=/src/index.js
There is also a PropsRoute implementation in the code.
Your example seems to be working for the string arguments. It's the array param selected which is giving you trouble.
The action creator that you are dispatching here, changeLocation, does not take the right arguments. Look at how you are calling it in your component:
changeLocation({
location: event.target.name,
checked: event.target.checked
});
When it is called from the URL query it is going to be called like:
changeLocation([Stockholm, Oslo]);
So obviously these do not match up. The existing changeLocation action can only handle one location at a time, so there's not a way to map the value from the URL to a payload that you can use with it. You will need to create a separate action.
const setLocation = (payload) => ({ type: "setLocation", payload });
case "setLocation":
return {...state, selected: payload};
My first approach to handle the array values was to implement the optional stringToValue and valueToString settings for the selected param.
This only kinda-sorta works. I can't get it to omit the param from the URL when it is set to the default value. I wonder if it's using a === check? As a hacky solution, I added a filter in the stringToValue to prevent the empty string from getting added to the locations array. But the selected= is always present in the URL.
selected: {
selector: (state) => state.selected,
action: setLocation,
stringToValue: (string) => string.split(",").filter(s => !!s),
valueToString: (value) => value.join(","),
defaultValue: []
}
This really annoyed me, so I followed this bit of advice from the docs:
Note you could equally well put the conversion to and from the string in the selector and action creator, respectively. The defaultValue should then of course be a string too.
And this approach worked much better.
selected: {
selector: (state) => state.selected.join(","),
action: (string) => setLocation(string.split(",")),
defaultValue: ""
}
With those changes you should have a shareable URL.
Forked Sandbox
Thanks Linda. The example I sent was what I referred to do my implementation. It wasn't my work.
Just letting you know that since my app uses PropsRoute I was able to use history props to push the state as params in url and share the url. I had to modify code to use params from url as state if it was available. This worked between tabs. Will be testing across machines.
this.props.history.push("/currenturl/" + state)
this.props.history.push("/currenturl/" + {testobject:{}})
this.props.match.params.testobject
wasn't able to implement redux-query-sync though.
Currently what i have is
http://www.example.com/_id
instead of displaying the generated id in the url i want to show the title of my post in the url. Such as
http://www.example.com/this_is_a_new_post
do i have to add the slug field in the collection for this? isn't there any any solution using which i can make a friendly url and i don't have to make another redundant field like slug?
P.S. I don't want to use packages. i guess it can be done without packages easily.
The simplest thing you can do is just to use /:title. Iron will automatically decode the title. Firefox handles such URLs pretty nicely. It just converts them, so the user sees the actual title including all special-chars. Also, all the iron helpers are encode the URL string correctly.
To create a slug you can use something like this function:
createURLSlug = function (url) {
var slugRegex = /[^\w\-\.\~]/g
while(slugRegex.test(url)) {
url = url.replace(slugRegex, '-')
}
return url
}
I used the wiki page on of allowed URL characters as a reference for this regex.
If you are using SimpleSchema you can also use an autoValue:
...
slug: {
type: String,
autoValue: function () {
return createURLSlug(this.field('title').value)
}
}
...
How can I use URL parameters with meteor.
The URL could look like this: http://my-meteor.example.com:3000?task_name=abcd1234
I want to use the 'task_name' (abcd1234) in the mongodb query in the meteor app.
eg.
Template.task_app.tasks = function () {
return Tasks.find({task_name: task_name});
};
Thanks.
You are probably going to want to use a router to take care of paths and rendering certain templates for different paths. The iron-router package is the best one available for that. If you aren't using it already I would highly recommend it.
Once you are using iron-router, getting the query strings and url parameters is made very simple. You can see the section of the documentation here: https://github.com/iron-meteor/iron-router/blob/devel/Guide.md#route-parameters
For the example you gave the route would look something like this:
Router.map(function () {
this.route('home', {
path: '/',
template: 'task_app'
data: function () {
// the data function is an example where this.params is available
// we can access params using this.params
// see the below paths that would match this route
var params = this.params;
// we can access query string params using this.params.query
var queryStringParams = this.params.query;
// query params are added to the 'query' object on this.params.
// given a browser path of: '/?task_name=abcd1234
// this.params.query.task_name => 'abcd1234'
return Tasks.findOne({task_name: this.params.query.task_name});
}
});
});
This would create a route which would render the 'task_app' template with a data context of the first task which matches the task name.
You can also access the url parameters and other route information from template helpers or other functions using Router.current() to get the current route. So for example in a helper you might use Router.current().params.query.task_name to get the current task name. Router.current() is a reactive elements so if it is used within the reactive computation the computation will re-run when any changes are made to the route.
To get understandable links to share, I don't want to put only the ._id in the url but the .name as well.
Router.map(function () {
this.route('here', {
path: 'here/:_id/:name/',
template: 'here'
})
})
The Problem is that the .name entry can have special characters like /.
www.example.com/here/1234/name_with special-characters like / (<-this slash) /
Is there a way to replace the slash (and other special characters) in iron-router?
(if there is a good way to handle this, maybe in some cases I don't even need the id anymore.)
If I want to use <a href="{{pathFor 'showCourse'}}">
I can not use a wildecardpath: 'here/:_id/*
Thanks
It's not specific to Iron Router, but JavaScript's native global functions encodeURIComponent and decodeURIComponent exist for just this purpose:
encodeURIComponent("foo/bar"); // returns "foo%2Fbar"
decodeURIComponent("foo%2Fbar"); // returns "foo/bar"
What I do in my projects is add a field called slug and write a function that generates an URL-friendly slug from the document's title and checks the collection to make sure the slug is unique (otherwise it appends "-2" or "-3" etc. as appropriate). With a slug or similar field that is unique per document, you can use it as the only query parameter and forgo the _id.
Expanding on Geoffrey Booth's answer, you can do this with a template helper.
Define a template helper to encode your name value (I made it global so it can be reused by all templates):
Template.registerHelper('encodeName', function() {
this.name = encodeURIComponent(this.name);
return this;
});
Then, in your templates, you can pass this function to iron-router's pathFor helper:
<a href="{{pathFor 'showCourse' encodeName}}">
This works for me on Meteor 1.1.0.2.