Crawlable javascript spa with pushstate SEO - javascript

i make a single page application. I had read the following article create-crawlable-pushstate.
I run just into problems using hashbang. This seems for me like a solution. But im not quite sure if i userstand what is going on there. Here is an example from the article :
// We're using jQuery functions to make our lives loads easier
$('nav a').click(function(e) {
url = $(this).attr("href");
//This function would get content from the server and insert it into the id="content" element
$.getJSON("content.php", {contentid : url},function (data) {
$("#content").html(data);
});
//This is where we update the address bar with the 'url' parameter
window.history.pushState('object', 'New Title', url);
//This stops the browser from actually following the link
e.preventDefault();
}
Thats great but how will google know that the content is available. The getJson function is asynchronous, so the state will be pushed before the content is loaded. My thought was that i call pushstate after content is loaded to show that the link is ready.
In my scenario a user clicks on a href.
Router catch hash change and call a function. (I can overwrite the click event to pushstate after content is generated.
Content will be loaded and generated. (Time pass)

Google doesn't care about the JavaScript. All it sees is the URLs.
Your server still needs to generate the appropriate page for each given URL.
With JS:
Client (browser, googlebot, whatever) asks for http://example.com/whatever/whatever/whatever
Server responds with the page for /whatever/whatever/whatever
Client clicks on link with:
href="/something/something/something
Ajax</li>
<li>preventDefault`
Client loads content with Ajax
Client changes URL to /something/something/something without reloading the whole page
Without JS:
Client (browser, googlebot, whatever) asks for http://example.com/whatever/whatever/whatever
Server responds with the page for /whatever/whatever/whatever
Client clicks on link with:
href="/something/something/something
Ajax</li>
<li>preventDefault`
Client goes to /something/something/something (since there is no JS to trigger the preventDefault)
Then later, someone goes directly to /something/something/something and the same applies. The server delivers the content for /something/something/something directly. Then JS does Ajax stuff when the click a link (if JS is available).

Related

Integrating HotJar in SPA with same URL

I'm trying to integrate Hotjar with an admin panel.
The way it currently works is some sort of SPA without page loads and neither URL changes.
It all happens under /index.php and then when we need to change a page, just send an AJAX request to load it's content.
From checking the documentation, Hotjar seems compatible with SPA's but only when there's a change in the URL (either query string or hash).
Is there a way to trigger in JS a page change to a page name (i.e. Main Page) ?
I've tried
hj('vpv', 'Main Page')
But the output seems weird
url: "http://mydomain.comTest Page"
Thanks.
You can track your changes manually by adding additional JavaScript after your AJAX calls.
Documentation:
To Manually Issue a State Change
hj('stateChange', 'some/relative/path');
Example:
Imaging that you have a SPA with base URL http://example.com/ and you want to track the main page and a page that gets dynamically loaded with AJAX once you click some button.
In order to do that, you would need to:
1) In your Hotjar account, create two heatmaps. For the main page, you can use the base URL http://example.com/. For the page that is going to be loaded dynamically, you can put a virtual URL, e.g. http://example.com/my-dynamic-page, which will be used only for recording and will not need to exist in your SPA.
2) In the JavaScript of your application, add the state change code after the AJAX call that will dynamically load the page.
You need to use the virtual URL that you defined in the previous step to let Hotjar know that this is a new page and you want to track it separately:
hj('stateChange', 'http://example.com/my-dynamic-page');

How to track exit links

I have a website with embedded videos. Each iframe comes from different website.
The problem is that some of them, are redirecting my visitors to their assigned destination without actions (click, hover, etc). And now Google is listing my website as suspicious.
Is there any php script to track every single exit link from my pages to another website?
Let's say i'm using Wordpress and have already created $table_name tracking 1-timestamp, 2-my page that was redirected, and 3-the destination of the external website/domain.
function the_function() {
// if there is any function
}
if ( the_function() == true // or false )
{
$wpdb->insert($table_name, array(
'timestamp' => $timestamp,
'page' => $my_page_redirected_to_a_different_domain,
'destination'=> $destination,
));
}
Or if there is any js script, no problem
There is no way to track down redirects in a general way - you have to trigger an event right before the redirect is processed, so you have to know how this happen.
Why ? Because a JS redirection is processed by the browser and not on the server side - which means the only way to trigger an SQL insert is to know how the redirection is triggered. This is basically what you want to achieve:
What you can do to locate the redirection
Search for every occurences of window.location in your JS files - you could search for the URL that you've been redirected too (all your local js files and the external ones you include)
Disable (with comments) the external <iframe> you're using. An iframe can do a window.top.location.href to redirect the main page.
An other way to redirect the page would be to trigger a click event on a link through JS. I guess by searching for the redirect URL in your js file you could locate that too.
Last, if the redirection happens before the page is load, it could a PHP redirection - looking for header calls that redirect to the URL in your php files would catch that.
What can be done when the redirect is found
It's a JS redirection (window.location)
If it's inside a local file, you can just comment it if you want to disable it, if you want to keep it but track it, add this code right before the window.location call (it's jQuery, it will make an AJAX request to /log-redirects.php) :
$.post( "/log-redirects.php", function( data ) {
// ADD the window.location line here
});
It's really important that you move the window.location call inside the AJAX callback, so the redirection will be made only when the ajax call is finished.
If the redirection happens in an external js, you could not probably do anything besides removing the whole JS file - maybe get the JS file content, remove the redirection and include it locally.
One thing you could try is to add a listener on the beforeunload event - though you'll have to do the correct check on the event object to see if it's the redirection you're looking for, as it'll catch any unload events.
window.addEventListener("beforeunload", function (e) {
// do something
return false; // will result to a prompt to the user asking him if he really want to redirect
// return this only for the redirect you're looking for
});
Please note that this method doesn't seems to be completely reliable.
It's from an <iframe>
You can add the sandbox attribute to the iframe to prevent it to do any redirect. Please note that this attribute is not supported in IE9 and lower.
<iframe src="http://youriframeurl.com/" sandbox=""></iframe>
It's a click event triggered through JS
You can do the same thing as for the first point. You just want to add a listener to the link (using on if it's generated after DOM is load) :
$('a#mylink').on('click', function(e) {
// do something
e.preventDefault(); // add this if you want to cancel the redirection
});
It's a header redirection (PHP)
That's an easy case - just add the code you want before the header call.
Conclusion
I suggest to work first with the beforeunload event to track the redirection - doing a console.log(event); could give you some insights on the cause of the redirection.
Good luck!

How do I pre-cache a page before it redirects to it?

As seen in YouTube, when you click a YT link it before redirecting you it preloads the layout of the page and then it redirect yoo it, for you to not having to see how the layout items load.
How do I make this with, JavaScript, PHP, HTTP, jQuery or with any other language?
I don't think you really understand what is going on behind the scenes at YouTube. You see, the template/layout doesn't always change. The data always changes. It isn't loading the layout (unless the new page has a different template, such as sending a message or viewing a user profile), it is fetching the data from a database and then it uses javascript to replace the current data on the page with the data it just fetched. It does this through AJAX. They use Python on the back end.
Basically... this is what happens when you click a link for a new video:
1) You click the link.
2) Some JavaScript code makes an XMLHttpRequest to a script on the server which processes the request. A progress bar appears on the screen.
3) The script on the server connects to a database and grabs the information... like other videos in the playlist, comments, the video description, etc. It does this by submitting a query to the database.
4) The query returns the information to the script which in turn organizes it and returns it to the AJAX request (asynchronously, of course).
5) The JavaScript receives the information that it was waiting for and updates the HTML of the page. The JavaScript also does some other stuff behind the scenes, like update the URL and browsing history so that you can hit your "back" button and return to the previous page that you were on. (If the template for the newly requested page is different, the JavaScript will restructure the HTML of the page appropriately.)

Is there any way to quickly and easily convert standard website loading to AJAX on entire website?

Maybe that's not a good question but I'm wondering if it would be somehow easily and quickly (with just 1 function perhaps?) possible to change ALL links on website from refreshing webpage to loading the URL that user clicked via AJAX?
My website has standard links everywhere but if you want to have mobile application for iPhone out of it you need to use AJAX everywhere (and perhaps HTML5 History API) because any link will open Safari browser.
Do you think there's any way to quickly convert every single link to delete current source code and load brand-new page without refreshing browser window? Or does it require manual coding and separate functions for every single set of links?
Example:
jQuery(document).on('a', 'click', function(){
// STEP1: AJAX call that will make PHP download page from link
// STEP2: Delete current source code and load new one (in this case including deletion of this function itself)
});
Do you think it would be possible or are there any pitfalls here?
I've done something similar to this. It's possible, but you may have to change a couple of things on server side.
In my case, i had some links with href = #, some of them had click triggers, so i wanted to keep them out.
In this function i check every link without href = #, and if they don't have a click event, i bind ajax.
bindAjaxLinks: function() {
$('a[href!="#"]').each(function() {
var eventObj = $(this).data('events');
if (!eventObj || !eventObj.click) {
// not a javascript link, do your thing
var link = $(this).attr('href');
if (link) {
$(this).click(function(event) {
event.preventDefault();
// do your ajax calling here.
});
}
}
});
Some considerations: In my case, i added an extra parameter, something like isAjax to every request i made with this function, and in backend i sent only a part of whole page(without head and some other markup). And later i replaced what is visible to user with this new html.
This caused a problem: if server responded with a redirect, i got the whole page, which i didn't want, so i made sure this isAjax parameter is kept after redirects, and that solved this problem.

Call JS function before redirect

The situation is as follows:
A user on the client side enters some data and presses a command button that initiates an ajax request. Depending on the input data the JSF Bean on the server side redirects to different pages. But in addition the HTML5 features localstorage respectively sessionstorage should be updated on client side, also depending on the results from the bean. For the storage some data entered from the user is necessary, so that the java script for the storage has to be within the original page.
Now, the problem seems to be that after the response the redirect is always done first, before executing the js function and so it is not possible to access the input data from the user on the client side of curse.
I tried things for calling the js function after pressing the command button like "oncomplete" on the client side using callback parameters (redirect takes place earlier) or RequestContext.execute from the server side (but this internally also uses the oncomplete event i think).
One possible solution I could imagine is to use window.onunload on client side and a hidden input formular to get the result of the bean. But isn't there a better solution?
You need to redirect by JS instead of by JSF. Return null from action method so that it returns to the same page and then execute the following script to perform a redirect in JS.
window.location = newURL;
If you use PrimeFaces with JSF then it's possible to make global override of PrimeFaces.ajax.ResponseProcessor.doRedirect in javascript to put any custom code before actual redirect happens:
PrimeFaces.ajax.ResponseProcessor.doRedirect = function(node) {
// <<<< your code is here >>>>
window.location = node.getAttribute('url');
}
Put this code in some js file and include it in all your pages.

Categories