I'm working on a SPA with Svelte. I have svelte-spa-router module installed. Nowhere seems to be documentation or examples how to add some object to your url.
This is easy in Vue:
router.push({ path: 'pathName', query: { someattribute: 'mygreatvalue' }})
In Svelte however the "push" only seems to support "location".
I tried some vanilla function but it adds the data in the wrong place.
My url looks like so:
myniftyspa.com/#/thepage
and I want:
myniftyspa.com/#/thepage/?someattribute=mygreatvalue
or:
myniftyspa.com/#/thepage/someattribute/mygreatvalue
it needs to stay on the page without reloading because I just want to store some data in the url this way. In the end it's about storing some ingredients information nested in an object that is being picked up after a revisit.
You can use vanilla window.history to set the current url without reload. Like so:
// address bar shows www.domain.com
window.history.pushState(null, '', window.location + '?foo=bar')
// address bar shows www.domain.com?foo=bar
I figured something out as a "solution" that works for now. Maybe it's helping someone with the same issue.
the object you want to be stored:
const ingrParams = [
{
id: 308,
gr: 100
},
{
id: 7,
gr: 100
},
{
id: 233,
gr: 80
}
];
The snippet:
push("/ingredients-to-nutrients/" + encodeURIComponent(JSON.stringify(ingrParams)));
let p = JSON.parse(params.paramnameyousetinrouter);
(push is an import of the svelte-spa-router module)
note: you need to do an initial push at onMount or else this push will be seen as a page change.
Related
So probably my explanation is awful, but i really don’t know how to express my problem or what to search for.
I got a site (www.example.com/blog.html) showing all blog post entries created in a headless cms (Strapi). The site receives the posts by making an url request and parsing the resulting JSON data. This data also contains an unique url slug for each post serving as an identifier.
I want to create one page for each blog post created in the headless cms based on a „template“ html.
What I tried is passing the urlslug as a url parameter (www.example.com/blog/article.html?id=*URLSLUG*) and then using this url parameter to fetch the corresponding post data from the cms. I followed this guide: https://strapi.io/blog/build-an-editorial-website-with-vanilla-java-script-and-strapi
It works, but I don’t want to rely on url parameters for seo reasons. Instead I want something like www.example.com/blog/*URLSLUG*. In other words: I want to have one page for each blog post entry in my headless cms based on a „template“ html.
Any suggestions?
Code can be added if necessary
well there is few options here:
The first one is most reliable, and easy but seems not that fancy as you want:
https://market.strapi.io/plugins/strapi-plugin-slugify
The main reason to use this solution is that it handles slug creation when you create post via REST api. The uuid field needs extra work when post created not from admin panel.
So second option is do it yourself style:
/api/article/controller/article.js
module.exports = createCoreController('api::article.article', ({strapi}) => ({
findOne(ctx){
const { slug } = ctx.params;
return strapi.db.query('api::article.article').findOne({where: {slug});
}
});
then in the routes create routes.js file
/api/article/routes/routes.js
module.exports = {
routes: [
{
method: 'GET',
path: '/articles/:slug'
handler: 'article.findOne'
}
]
}
then if you want to create articles for outside of admin, create lifecycles.js in
/api/article/content-types/article/lifecycles.js
module.exports = {
async beforeCreate(event) {
// here you have to do something like
let slug = slugify(event.result.name);
let isNotFree = await strapi.db.query("api::article.article").findOne({where: {slug}});
if (Boolean(!isNotFree)) // < not sure prolly need an empty object check
for (let i = 1; i < 9999 ; i++) {
slug = `${slug}-${i}`;
isNotFree = await strapi.db.query("api::article.article").findOne({where: {slug}});
if (Boolean(!isNotFree))
break;
}
event.result.slug = slug
}
}
pleas note the lifecycle code is just a first thing came to my mind, should be tested and optimized prolly
the implementation gives you the findOne controller, you gonna need to do it for each other update, delete, etc...
I am working on a REACT JS project in an attempt to create a small Todo List app.
I have my data in a JSON file, currently hosted on jsonbin.io, in a format that looks like this...
{
"moduleAccess": {
"tasks": [
{
"email": "campbell#yahoo.com",
"id": 0,
"task_name": "Call mom",
"due_date": 44875,
"completed": true
},
{
"email": "palsner593#gmail.com",
"id": 1,
"task_name": "Buy eggs",
"due_date": 44880,
"completed": false
},
{
"email": "rob#gmail.com",
"id": 2,
"task_name": "Go to dog park",
"due_date": 44879,
"completed": false
}
]
}
}
Currently, I fetch the data using jsonbin.io's API. The data is brought into a variable called Tasks. If a user updates a specific to-do item, deletes a to-do item, or creates a new one, all those changes are put back into the Tasks variable. I can then send push those tasks to the server.
What I explained above works fine; however, the caveat is that I would like to allow multiple users to log in and then pull only the Todo items that pertain to their respective email.
Say, campbell#yahoo.com is logged in to my app. In this case, in my fetch pull request, I can specify that I would only like records with campbell#yahoo.com
async function loadData() {
const newPath = '$..tasks[?(#.email==' + campbell#yahoo.com + ')]';
console.log(newPath);
const url = 'https://api.jsonbin.io/v3/b/*binid*?meta=false'
const response = await
fetch(url, {
method: "GET",
headers: {
"X-Master-Key": key,
"X-JSON-Path": newPath
}
});
const data = await response.json();
setTasks([...data]); //or whatever
console.log(tasks);
}
This concept works as well. However, when pushing my task data back to a server after a user has made changes, I encounter an issue. The API I am using does not seem to allow parameters for specifying the JSON path upon PUSH. JSON-PATH is only allowed for a pull request. So when I push data to the server, it seems as if all JSON data will be overwritten, regardless of the user.
Does anybody have an alternative way to push/pull user-specific data? I am sorry if the detail I have provided is unnecessary. Not sure what the easiest way to approach this problem is for a react app.
Any help is appreciated. Thanks!
I did a little research in jsonbin.io API and came up with a solution that might work.
So I'm not really sure that this will work, but still.
When creating a new bin, you can add it to some collection using X-Collection-Id. So you might be able to make next flow:
When user register, create a separate bin for tasks for this user
Add user with bin id to some users collection where you will have all your users
When user auth, get his bin id using filters that you used in your code and store it for future use somewhere in your app.
After this you will be able to fetch users tasks by that bin id and modify it, cause now it will be a separate bin for each user and you can simply override all of its content.
Hope this works.
I can't seem to find a solution when I get a push notification and click on it redirects me to a screen, chat, etc. link to push notification.
I would also like to add a square image to the side and could not find an answer.
The push notifications are sent from a NodeJS server I looked at the docs and search the internet and I did not find anything of interest.
https://docs.expo.dev/versions/latest/sdk/notifications/#managing-notification-categories-interactive-notifications
https://github.com/expo/expo-server-sdk-node
Thank you in advance for your answers ❤️
I'm not quite sure about the square image, but in order to handle redirects you can look at this documentation from expo: https://docs.expo.dev/push-notifications/receiving-notifications/.
You can then pass the data you need for your redirect (i.e. notification_type, relevant id etc) via the data property on your message (this will need to be done wherever the message is created, which from your question is from the node api):
messages.push({
to: pushToken,
body: 'This is a test notification',
data: { notification_type: 'something', id: 'something_else' },
});
It is then up to you to decide how to handle that message based on the extra data you have provided.
For example, taking the code provided in the link above as an example, you could have a handle function as follows:
_handleNotification = response => {
const data = response.notification.request.content;
if (data.type === "new_message") {
// navigate to MessageScreen with data.id as param
} else {
// do something else based on the type or...
}
};
For some reason when I try to send the eventId parameter a second time after the page has loaded, the Facebook pixel is not picking it up even though the eventId has a value.
Any idea on how to solve this? I am using react with gatsby dynamic routing. Do I need to somehow reinstantiate fbq and if so, how?
This appears to only be an issue with the PageView event.
fbq("track", "PageView", { ...userData }, { eventId: eventId })
Set this option true in place init Facebook Pixel:
fbq.disablePushState = true
fbq.allowDuplicatePageViews = true
Building a jobs board. Need to know if the user clicked on our link from monster.com, jobs.com, foobar.com, etc. This needs to happen in the code, as I need to send it to an API.
What is the best way to accomplish this?
I tried searching around, but can only find articles on internal routing, e.g.:
How to get previous url in react gatsby
If I need to do this in plain Javascript (not available "out-of-the-box"), please point me in the right direction there too. Not even sure what to google for this other than "UTM parameters". We are using Google Analytics and the marketing team is including utm params in the links, if that helps.
In gatsby each page component has a location prop with some useful info. So you could do something like:
import React from "react"
const IndexPage = ({ location }) => {
console.log(location.search.split("?")[1].split("&"))
return (
<div>
My homepage
</div>
)
}
export default IndexPage
So visiting https://myapp.com/?campaign=foo&id=bar would log ["campaign=foo", "id=bar"]. With that info, you could decide how and when to communicate with your APIs to log the relevant info.
This question was very vague, because I did not understand what I was asking when I posted it. There is two scenarios here that should help you get started. If you have specific questions, follow up - I will try to help.
Scenario 1 (will most likely NOT work, but here for completeness): You are getting referrals from websites you are not at all associated with. For example, you run mycoolsite.com and someone at someforum.com linked to you. The ONLY way you are going to be able to know this without anything additional is if someforum.com sends something called a Referer Request Header. Many popular sites do not.
Scenario 2: Your marketing team pays someone to link to you for a specific promotion. E.g., your marketing team tells someforum.com to link mycoolsite.com for money or as a favor. In this case, they can request that scenario 1 be followed OR, more likely, they can include something called utm params, e.g. when they send the link it's not mycoolsite.com?utm_campaign=monster&utm_source=monsterjobs
When the request comes in to your site, you can then pull these utm params out, to identify which campaign is working.
The code for that looks something like this:
function buildUtmInfoString(currentUrlString) {
const url = new URL(currentUrlString);
let referrerString = '';
utmParamNames.forEach(paramName => {
const paramValue = url.searchParams.get(paramName.standard);
if(!paramValue) {
return;
}
const paramString = `${paramName.colloquial}: ${paramValue}, `;
referrerString += paramString;
});
referrerString = referrerString.substring(0, referrerString.length-2);
return referrerString;
}
Note that you might need to look up utm param standard names, they are supported by Google Analytics out of the box, if your company uses that, but you can use them without GA.
const standardUtmParamNames = {
SOURCE: 'utm_source',
MEDIUM: 'utm_medium',
CAMPAIGN: 'utm_campaign',
TERM: 'utm_term',
CONTENT: 'utm_content'
};
const utmParamNames = [
{
standard: standardUtmParamNames.SOURCE,
colloquial: 'Source'
},
{
standard: standardUtmParamNames.MEDIUM,
colloquial: 'Medium'
},
{
standard: standardUtmParamNames.CAMPAIGN,
colloquial: 'Campaign'
},
{
standard: standardUtmParamNames.TERM,
colloquial: 'Term'
},
{
standard: standardUtmParamNames.CONTENT,
colloquial: 'Content'
}
];
export default utmParamNames;
Note that there are also hacks to accomplish this, but they are not reliable and can be seen as abuse of your user's privacy, so they aren't viable business solutions and I don't recommend wasting time on them.