Is this the right package to solve my geo-targeting problem?
Hi all,
This looks like a really useful package.
My company has a specific problem to solve on an Umbraco site we're currently building. We have a "Markets" section on the site - and some of the markets described within the section have different titles (and also content) depending on which country the visitor is based in (all content is in English so far, so its a multi-region issue rather than multi-lingual).
For example, the American's refer to "Defense", rest of the world "Defence".
My plan is to create a separate branch of pages within this specific section of the site which are US-centric, and tag them as only being applicable to visitors based in the USA. The corresponding "generic" (rest of the world) pages are tagged as only being applicable to visitors outside the USA.
So I setup two groups:
"Is in America" (Visitor is located in: United States)
"Is not in America" (Visitor is not located in: United States)
I tagged my US-centric page with the "Is in America" group, and my generic "rest of the world" page with "Is not in America". When outputting the site navigation, I use the "ShowToVisitor()" method to only display the nav options that are relevant to the current visitor.
This seems to work well.
Small edge case, in that if the visitor is using a private network address (e.g. 127.0.0.1), or the lookup of their IP fails for some reason - they end up being a member of neither group (so don't see any nav options).
Just wondered when using the Personalisation group picker on my content page, whether there is some way of using a not option (i.e. the content is only relevant if the visitor is not in a particular group) - as this would solve that problem.
Any other hints, advice or feedback on whether this package is the right way to tackle the problem would be appreciated.
One thing you can do that you may have missed is set a value in configuration, specifically the personalisationGroups.testFixedIp setting. This would be used in preference to anything detected from the client IP headers and so, when working locally (and thus getting 127.0.0.1 detected), you can override this with a known IP.
That would allow you to locally test "in US" and "outside US" (by configuring a known US and non-US IP).
In the (hopefully rare) case though where the IP can't be located, or the country for an IP can't be found, there's still an issue with the user not being in either group. I think on reflection I should change the logic here.
Currently if we don't identify the country of a user - we return false when we are checking if they are in, or if they are not in, the US. Perhaps strictly that's correct, but it's probably more realistic to return true for the "not in the US" check.
Let me know what you think and perhaps will look to change the behaviour of this criteria here.
Many thanks for your feedback. Yes, I was playing with the testFixedIp, really helped with testing.
Having "not in US" set to true when the IP can't be identified would be amazing! Or perhaps a rule you could add to a content page that states something like "User's location can't be identified".
Then, you could have the US page set up to display if the user is in the USA, and the other page to show if the location couldn't be identified or the location is outside the US.
I like that idea, a more explicit solution and gives the developer the option to treat "can't locate country" how they feel is best for their application. Thanks.
Thanks for taking the suggestion on-board. Not intending to pressure at all, but just curious - if you do decide to implement that, feature when do you think it would be added?
I've got this prepared Steve. Wonder if you'd mind first though please being a second pair of eyes on the code and/or trying out the update on your solution (you can download the dll from this link)?
Thanks if so - and if all looks good I'll prepare a release.
OK, I copied the DLL in to the BIN folder and then setup my "Is not US" personalisation group to match "any" of:
"Visitor is not located in: United States"
"Visitor cannot be located"
When I now visit the site from localhost, I get the correct navigation options (it treats localhost as a non-US visitor). If I "force" a US IP address, then I'm still identified as being a US visitor.
So thank you - it seems to work just fine for my use case.
One other minor comment (just intended as a comment, not necessarily a bug report)... If I change the IP address in web.config (i.e. to change from a UK to US IP) it seems to add the newly matched personalisation group node ID to the "sessionMatchedGroups" session cookie (rather than re-evaluating the whole list to remove the group ID that no longer matches). So I can end up being a member of both the groups "Non US" and "US". For it to happen in production, it would be a real edge case - but I have come across a few companies in the past that route web traffic out through a proxy where the internet facing IP might not always be the same for each page-load (although I guess you'd hope it was at least in the same country).
Thanks for checking Steve. I've pushed out an update to our and NuGet for version 0.3.4,
And thanks for the further observation, it's valid but I think actually the current behaviour is correct given the intention of the "Duration in group" = "Per session" setting.
With that, you are saying "once in a group, you remain in it for the duration of the session". So for example if we have a criteria based on a querystring that's there when you hit the home page, but gone if you return to the home page after navigating the site, you remain in the group.
Clearly changing country within a session is less likely! But if somehow you did, then it should still likely behave the same.
If you don't want this behaviour, you could set "Duration in group" = "Per page request". Then it'll re-evaluate on every page request. In the case of the country look-up by IP, this is cached, so likely you wouldn't incur too much performance hit.
Is there a way that from a template/view (or c# class) that I can call a method to discover the country the current visitor is located in (as calculated by your package)? If not already possible, would that be easy to add?
Within my personalised content page, I have a content block that calls an API on another server to retrieve a list of case studies - being able to pass that API an ISO country code would help me to filter or sort the project results so they are relevant to the visitor.
EDIT: sifting through your source code, I can see that I can do this:
var _ipProvider = new HttpContextIpProvider();
var _geoProvider = new MaxMindGeoLocationProvider();
var ip = _ipProvider.GetIp();
var country = _geoProvider.GetCountryFromIp(ip);
if(country!=null)
{
@(country.Name)<text> / </text>@(country.Code)
}
Which seems to work just fine - but is it the most efficient way of doing it?
Yes, those classes are available to you from the package (as they are defined as public). They aren't really intended as part of the public API for working with the personalisation features, but there's no reason why you can't use them as you have.
Massively of off topic, but something to mention on the subject of Geo IP. Be a bit careful with the IP address your pulling out of the request if you're using a CDN as you'll often not get the IP address of the person, but the IP address as channeled through the CDN.
Most CDN's have a request variable that will give you true IP address, so worth double checking if you're going this route.
It's a good point. I've tried to search through all the possible headers from CDN providers to find the original IP, so on that score, the package should work as expected.
However, there's likely a bigger issue with the whole idea of server-side personalisation and CDN caching - in that if the same URL might return different content for different visitors, it's likely not going to work as the CDN will may be returning content personalised for one user, to another.
I've mused on a way around this in the in some ways similar case of output caching here and here.
Thanks for the heads up. We're going to host our site as an Azure application. Not sure if this is likely to be a problem for us? I imagine it would perhaps be an issue if we were using Cloudflare (perhaps?)
Is this the right package to solve my geo-targeting problem?
Hi all,
This looks like a really useful package.
My company has a specific problem to solve on an Umbraco site we're currently building. We have a "Markets" section on the site - and some of the markets described within the section have different titles (and also content) depending on which country the visitor is based in (all content is in English so far, so its a multi-region issue rather than multi-lingual).
For example, the American's refer to "Defense", rest of the world "Defence".
My plan is to create a separate branch of pages within this specific section of the site which are US-centric, and tag them as only being applicable to visitors based in the USA. The corresponding "generic" (rest of the world) pages are tagged as only being applicable to visitors outside the USA.
So I setup two groups:
I tagged my US-centric page with the "Is in America" group, and my generic "rest of the world" page with "Is not in America". When outputting the site navigation, I use the "ShowToVisitor()" method to only display the nav options that are relevant to the current visitor.
This seems to work well.
Small edge case, in that if the visitor is using a private network address (e.g. 127.0.0.1), or the lookup of their IP fails for some reason - they end up being a member of neither group (so don't see any nav options).
Just wondered when using the Personalisation group picker on my content page, whether there is some way of using a not option (i.e. the content is only relevant if the visitor is not in a particular group) - as this would solve that problem.
Any other hints, advice or feedback on whether this package is the right way to tackle the problem would be appreciated.
Many thanks,
Steve.
Hi Steve
One thing you can do that you may have missed is set a value in configuration, specifically the personalisationGroups.testFixedIp setting. This would be used in preference to anything detected from the client IP headers and so, when working locally (and thus getting 127.0.0.1 detected), you can override this with a known IP.
That would allow you to locally test "in US" and "outside US" (by configuring a known US and non-US IP).
In the (hopefully rare) case though where the IP can't be located, or the country for an IP can't be found, there's still an issue with the user not being in either group. I think on reflection I should change the logic here.
Currently if we don't identify the country of a user - we return false when we are checking if they are in, or if they are not in, the US. Perhaps strictly that's correct, but it's probably more realistic to return true for the "not in the US" check.
Let me know what you think and perhaps will look to change the behaviour of this criteria here.
Andy
Many thanks for your feedback. Yes, I was playing with the testFixedIp, really helped with testing.
Having "not in US" set to true when the IP can't be identified would be amazing! Or perhaps a rule you could add to a content page that states something like "User's location can't be identified".
Then, you could have the US page set up to display if the user is in the USA, and the other page to show if the location couldn't be identified or the location is outside the US.
Thank you,
Steve.
I like that idea, a more explicit solution and gives the developer the option to treat "can't locate country" how they feel is best for their application. Thanks.
Thanks for taking the suggestion on-board. Not intending to pressure at all, but just curious - if you do decide to implement that, feature when do you think it would be added?
I should get chance this week or over the weekend.
I've got this prepared Steve. Wonder if you'd mind first though please being a second pair of eyes on the code and/or trying out the update on your solution (you can download the dll from this link)?
Thanks if so - and if all looks good I'll prepare a release.
Andy
Hi Andy,
Many thanks!
I've been off work today, but will have a look first thing tomorrow morning.
Kind regards,
Steve.
Hello Andy,
OK, I copied the DLL in to the BIN folder and then setup my "Is not US" personalisation group to match "any" of:
When I now visit the site from localhost, I get the correct navigation options (it treats localhost as a non-US visitor). If I "force" a US IP address, then I'm still identified as being a US visitor.
So thank you - it seems to work just fine for my use case.
One other minor comment (just intended as a comment, not necessarily a bug report)... If I change the IP address in web.config (i.e. to change from a UK to US IP) it seems to add the newly matched personalisation group node ID to the "sessionMatchedGroups" session cookie (rather than re-evaluating the whole list to remove the group ID that no longer matches). So I can end up being a member of both the groups "Non US" and "US". For it to happen in production, it would be a real edge case - but I have come across a few companies in the past that route web traffic out through a proxy where the internet facing IP might not always be the same for each page-load (although I guess you'd hope it was at least in the same country).
Many thanks,
Steve.
Thanks for checking Steve. I've pushed out an update to our and NuGet for version 0.3.4,
And thanks for the further observation, it's valid but I think actually the current behaviour is correct given the intention of the "Duration in group" = "Per session" setting.
With that, you are saying "once in a group, you remain in it for the duration of the session". So for example if we have a criteria based on a querystring that's there when you hit the home page, but gone if you return to the home page after navigating the site, you remain in the group.
Clearly changing country within a session is less likely! But if somehow you did, then it should still likely behave the same.
If you don't want this behaviour, you could set "Duration in group" = "Per page request". Then it'll re-evaluate on every page request. In the case of the country look-up by IP, this is cached, so likely you wouldn't incur too much performance hit.
Andy
Hi Andy,
Sorry, one further question/suggestion.
Is there a way that from a template/view (or c# class) that I can call a method to discover the country the current visitor is located in (as calculated by your package)? If not already possible, would that be easy to add?
Within my personalised content page, I have a content block that calls an API on another server to retrieve a list of case studies - being able to pass that API an ISO country code would help me to filter or sort the project results so they are relevant to the visitor.
EDIT: sifting through your source code, I can see that I can do this:
Which seems to work just fine - but is it the most efficient way of doing it?
Thank you,
Steve.
Yes, those classes are available to you from the package (as they are defined as public). They aren't really intended as part of the public API for working with the personalisation features, but there's no reason why you can't use them as you have.
Massively of off topic, but something to mention on the subject of Geo IP. Be a bit careful with the IP address your pulling out of the request if you're using a CDN as you'll often not get the IP address of the person, but the IP address as channeled through the CDN.
Most CDN's have a request variable that will give you true IP address, so worth double checking if you're going this route.
It's a good point. I've tried to search through all the possible headers from CDN providers to find the original IP, so on that score, the package should work as expected.
However, there's likely a bigger issue with the whole idea of server-side personalisation and CDN caching - in that if the same URL might return different content for different visitors, it's likely not going to work as the CDN will may be returning content personalised for one user, to another.
I've mused on a way around this in the in some ways similar case of output caching here and here.
Thanks for the heads up. We're going to host our site as an Azure application. Not sure if this is likely to be a problem for us? I imagine it would perhaps be an issue if we were using Cloudflare (perhaps?)
Should be no problem with Azure, but yes, you'd need to check carefully if you use some form of CDN in front of it.
is working on a reply...