I've been putting together a web page for a desktop application I've started developing, and I'd really like to take advantage of HTML5 technologies and dynamic content with JavaScript. Basically, if one visits the "root" page (index.php, or just the directory name) in their browser, sections for info, about, FAQs, and a contact form will all be visible (except for the contact form; clicking on the heading of its section will trigger a jQuery animation to reveal it). On the left side of the page I have a basic navigation with links to home, about, FAQs, and contact. The anchors for these links are "#!/home", "#!/about", "#!/faq" and "#!/contact" (respectively). When one of these is clicked, JavaScript/jQuery will hide all elements save for the header, footer, and the section to which the hashbang pertains (for the contact form, it will also remove the click handler for the header of the section because it doesn't need to and shouldn't be able to be hidden when it is the sole content of the page). Currently I am using this:
window.onload = (function() {
switch(location.hash) {
case "#!/contact":
$("body > *:not(section#contact, nav, header, footer)").hide();
$("#contact > #labels, #contact > form").slideDown('slow');
// and similar for the other hashbang URIs
}
if (location.hash == "#!/" || location.hash == "#!/home" || !eval(location.hash)) {
$("a[href='#!/contact']").click(function() {
$("#contact > #labels, #contact > form").slideDown('slow');
});
}
// similar for the other hashbangs
});
I'm almost certain there is a better way to do this, and I would also like to make sure that this page and its dynamic content are properly crawlable by Google's bots. Should I be using PHP to do this properly? How so?
Thanks!
This video tutorial on CSS Tricks by Chris Coyier goes over some best practice to implement something like this. A main point is to make sure your application will work with or without javascript turned on.
Related
I need some help to better understand SEO with ajax loaded content.
Here the context:
I have a single.php where content is dynamically generated (with php and an xml database) for each single post.
I load a container of this single.php inside my index.php page via ajax.
Here the working script:
$.ajaxSetup({cache:false});
$(".phplink").click(function(){
var post_link = $(this).attr("href");
window.location.hash = "!"+ post_link ;
$("#ajaxify_container").html("loading...");
$("#ajaxify_container").load('single.php?blog_no='+post_link+' #container');
return false;
});
$(window).hashchange( function(){
var hash = window.location.hash;
var hash = location.hash.replace("#!","");
if(hash != '') {
var post_link = hash;
$("#ajaxify_container").html("loading...");
$("#ajaxify_container").load('single.php?blog_no='+post_link+' #container');
}
else {
$.get(hash, function (data) {
$("#ajaxify_container").html('');
});
}
});
$(window).hashchange();
An example of a link in index.php (when I click on a link I've got in url website.com/#!12) :
<a class="phplink" href="12">Post 12</a>
And in my .htaccess file I added this lines to rewrite properly the url:
Options +FollowSymLinks
RewriteEngine on
RewriteRule /([0-9]+)$ /single.php?blog_no=$1
Everything works fine... (by the way, my single.php is SEO friendly "alone" and works without javascript)
However, by using ajax like this, with dynamic php page, is it still SEO friendly?
I know that ajax is difficult to be crawled. What is the best way to have a good (not the best, something correct) SEO with ajax content?
Regarding the structure of the link, I don't fully understand what google bot will crawl.
Because of the href="12", so the dynamic href="/single.php?blog_no=12".
In the web browser :
website.com/single.php?blog_no=12 and website.com/12 load only my single.php page
website.com/#!12 load my index.php page with a container loaded from website.com/single.php?blog_no=12
Of course I only want that google crawls the hashbang url...
(EDIT: if I open the link in a new tab with right click, it loads the single.php (that I don't want). It seems to be a normal behavior but...I want to prevent it)
Sorry for my English, I'm French.
Dynamically loaded content is generally hard to get right from an SEO perspective. Your description is a little confusing, but I think I have an idea of what you're looking for.
First of all, there are mainly two ways with which Google finds out about pages on your site:
A Sitemap (Google likes XML sitemaps) - A file that tells Google every page on your site to index
Links - Google will follow any internal link on pages it tries to index unless they are marked with rel="nofollow"
There's also links in and some other stuff, but for the purposes of this explanation...lets ignore those.
Anyway, unless you're explicitly telling Google that website.com/single.php?blog_no=12 exists, it's going to have a hard time finding it. To be honest, I'm not sure how Google will handle something like href="12", it may try to follow that link to website.com/12 which may effect your ranking if there is nothing there. So in the end, you might want to add rel="nofollow" to your AJAX trigger links.
A good way to handle AJAX and dynamically loaded content is to make sure fallbacks are in place, for example if you have something like href="single/12 set up to load some content with AJAX, you should also have a fallback page that doesn't use JS/AJAX. This ensures that both search engine bots, and users without Javascript can see that content if it otherwise wouldn't have been visible anywhere else.
Last small tidbit, if you test your links on something like http://www.dnsqueries.com/en/googlebot_simulator.php and they turn up with errors, or blank pages (search engine bots don't use javascript) you should nofollow those links, or setup fallback pages
Nevermind...this is the last thing. You should go a couple steps further with your htaccess rewrite to make your URLs completely clean of query strings. For example website.com/single/blog/12 is better than website.com/single.php?blog_no=12 for both SEO and users.
Okay, first off, I am not well-versed in JS or PHP. I can usually change an existing script around to do what I'd like, but not write something from scratch. Any URLs I mention in this for examples are made-up.
With that in mind, I am designing a page using a template that has CSS, PHP, and JS all of which I have really modified. Each page has a header, a nav bar, and a footer that are called with an include statement. I understand that part. However, on ONE of the pages, I would like to have a different nav-bar, and it won't change.
What I have noticed: The JS seems to change the clicked URLs from, say http://www.example.com/test.php to http://www.example.com/#test.php
What would be the purpose for that? Also... if I manually TAKE OUT the hashtag in the URL on the page that I want the new nav-bar, the new nav-bar shows! However, then if I switch pages, it'll make the end of the URL like ...test.php#newpage.php
So I either need to figure out how to modify this to NOT put the hashtag in the URL (but if there is a compelling reason for it, of course, it can stay), OR how to get that one page to show the alternate nav-bar. The alternate nav-bar is a table of contents, so the html has hashtags in it to direct users to specific parts of the page... could those hashtags in the html be conflicting somehow and that is why it won't show up, or??? GAH!
Any help would be appreciated.
Okay, here is part of the javascript... it is the only section where it looks like it is referring to # in the URL:
var $fadeWrapper = $("#fade-wrapper"),
$allNav = $("#main-nav a"),
$allListItems = $("#main-nav li"),
url = '',
liClass = '',
hash = window.location.hash,
$ajaxLoader = $("#ajax-loader");
$("body").attr("id", "");
if (hash) {
hash = hash.substring(1);
liClass = hash.substring(0,hash.length-4);
url = hash + " #inside-content";
$fadeWrapper.load(url);
$("." + liClass).addClass("active");
} else {
$("#main-nav li:first").addClass("active");
}
*UPDATE: I have decided to just remove the javascript altogether. In doing some reading, I have come to the conclusion that the hashtag is there just so the script can tell which page is active, in order for the CSS to highlight one of the items in the navbar. It also has something to do with the animated gif that would show when you navigate pages. Neither one of those items are important enough for me to pull more of my hair out trying to figure out this stuff :D Thank you for your suggestions, though! *
The hash tags are added most likely because the links you are clicking have an href value of #.
Couldn't you just create a new header file (if that is where the navbar code is), modify the navbar how you want in that header file, and include the new file instead of the current header on the page where you want the different navbar?
I want to include the same navigation menu on multiple pages, however I do not have PHP support, nor can I affect my server in any other way.
I want to avoid simply copying and pasting the html onto all the pages as this would make updating the menu a pain.
The two options I can think of are as follows:
1) Have all the content exist on one page, then determine which content to show based on a keyword appended to the url:
example.com/index?home
example.com/index?news
2) Include a javascript file that has a function that writes the menu out and call the function on each page
function setupMenu() {
$("#nav").html("<ul class='nav'><li>home</li><li>news</li></ul>");
}
With Option 1, the updating process would consist of editing one nav menu on the one page
With Option 2, updating would mean changing the function in the javascript file
My concern with Option 1 is that the page would have to load a lot of content that it wouldn't need to display. My concern for Option 2 may seem trivial but it is that the code can get messy.
Are there any reasons doing it one way would be better than the other? Or is there a third superior option that I'm missing?
You have a few options, each with its own advantages and drawbacks:
Server Side Includes, or SSI. If you don't have PHP there's a good chance you don't have SSI either, and this option requires some irritating mucking-about with your .htaccess file. Check Dominic P.'s answer for a writeup of SSI. The benefit of SSI over JavaScript or Frames is that it doesn't require the user to have JS enabled - which a lot of users don't - and it also doesn't present any navigational difficulties.
Frames. You could either use standard frames to put the navigation in its own separate file, and with the correct styling it would be seamless. You could also use an iframe to place your navigation in an arbitrary part of the site, like a sidebar or whatever. The downside to frames, particularly standard frames, is that they tend to make bookmarking, links and the forward/back buttons behave oddly. On the upside, frames don't need browser compliance or server support.
JavaScript. You can refer to any of the other answers for excellent explanations of the JS solution, particularly if you're using jQuery. However, if your site isn't otherwise dynamic enough that your users will want to have JavaScript enabled, this will mean that a large number of your viewers will not see the menu at all - bad, definitely.
-
Yes use .load jQuery ajax function
$('#result').load('ajax/menu.html');
That way your code stays clean, and you can just edit the includes in seperate HTML files just like PHP.
You should consider AJAX for this task. Include a third party library like jQuery and load the separate HTML files inside placeholders, targeting them by ID.
E.g, in your main HTML page:
<div id="mymenu"></div>
Also, in your main HTML, but in the HEAD section:
$('#mymenu').load('navigation.html');
But your best bet would be to switch to a hosting that supports PHP or any other server-side includes. This will make your life a lot easier.
Check out Server Side Includes. I don't have a whole lot of experience with them, but from what I recall, they are designed to be a solution to just your problem.
Server-side includes: http://www.freewebmasterhelp.com/tutorials/ssi/
You can use HTML Imports http://w3c.github.io/webcomponents/spec/imports/
Here is an example from http://www.html5rocks.com/en/tutorials/webcomponents/imports/
warnings.html contains
<div class="warning">
<style scoped>
h3 {
color: red;
}
</style>
<h3>Warning!</h3>
<p>This page is under construction</p>
</div>
<div class="outdated">
<h3>Heads up!</h3>
<p>This content may be out of date</p>
</div>
Then index.html could contain
<head>
<link rel="import" href="warnings.html">
</head>
<body>
...
<script>
var link = document.querySelector('link[rel="import"]');
var content = link.import;
// Grab DOM from warning.html's document.
var el = content.querySelector('.warning');
document.body.appendChild(el.cloneNode(true));
</script>
</body>
I have a navigation system that I wanted to make compatible with both javascript disabled clients and Ajax capable ones.
for now I have dynamic links like "index.php?page=/cat/page.php" generated inside navigation.
<li id="sidebaritem"><a href="index.php?page=<?php echo "$dirArray[$index]/$subdirArray[$subindex]"; echo $title; ?></a></li>
so when index has "page" variable, it loads that page inside main container.
but I also like to make it load onclick with ajax(jquery included). so I added this code:
$(document).ready(function(){
$('li #sidebaritem').click(function() {
//Page Load code goes here
});
});
This is not working, because as I click the link, right after li->click occurs it redirects to page which Anchor tag is pointing to(of course it dose).
I had spent some time looking for a tutorial on this subject but I found nothing useful.
How can I make it work?
Is this good from SEO Point of view?
I saw this article using hash, Is this good for SEO and if it is how can I make it work on Java Disabled machines?
Sorry for poor English, I'm new in this subject and I'm learning as I go.
First of all Java and JavaScript are two separate things and you're working with JavaScript. Second of all you should replace id="sidebaritem" with class="sidebaritem" unless the id's are unique, but from your given code I don't think it is. Also in jQuery and CSS (which is where the selectors are coming from) if you use li space #id it means that you're trying to select a child element of li with an id #sidebaritem. So you might do li#sidebaritem or if the id's aren't unique li.sidebaritem
So you should try:
<li class="sidebaritem"><a href="index.php?page=<?php echo "$dirArray[$index]/$subdirArray[$subindex]"; echo $title; ?></a></li>
and
$(document).ready(function(){
$('li.sidebaritem a').click(function() {
$("#your-main-container").load($(this).attr('href'));
return false; //prevent click from redirection
});
});
About the SEO part:
These links aren't SEO friendly, because they don't contain the keywords of the title/description of your page (As far as I can tell). To improve the site performance in search engines you'll need to replace these with something like /cat/this-is-my-amazing-seo-friendly-page/. So you might want to replace the url (which will be rendered from the title) of the page into a SEO friendly . Here's a little snippet of code that will do the job.
function replaceLink($url) {
$url = preg_replace("/[^a-zA-Z0-9\-\s]/", '', $url); //find any other symbols than letters or numbers and replace them with an empty string
$url = preg_replace("/\s+/", '-', $url); //find all spaces and replace them with a dash
return $url;
}
So if you've got a page title: This is my amazing SEO friendly page pass it into this little function like this:
$link = replaceLink("This is my amazing SEO friendly page");
and you'll get This-is-my-amazing-SEO-friendly-page
Obviously this is just one of the basics for improving On-site SEO. You can read more about On-site seo here
Also. From the search engine perspective your AJAX page load will have no impact as long as the real links are specified in the menu and they work without JavaScript enabled.
Hope this helps
I have page which created dynamically.
Now I want to add ajax function, so I want to add if statement to change the outputs.
if(js is on){
...
...
echo "js is on";
}else{
...
echo "js is off";
}
Is there any way I can detect if js is on with php?
Or is there any way I can remove/hide it by jquery?
Thanks in advance.
PHP is executed before any browser action takes place, so no, PHP cannot directly detect whether the user has Javascript on or off.
You must provide a bit more info on what you're doing for us to find you a workaround. In PHP, it is possible to detect whether the call was made via AJAX or not using the $_SERVER['X_HTTP_REQUESTED_WITH'] global variable which jQuery will set automatically.
If you need to show an element when Javascript is enabled, you can first hide the element with CSS and enable it with Javascript/jQuery. The same goes the other way around also.
You can't do that in PHP because the page is rendered by the time you know. And apart from some crazy redirect scenario, your best bet may be to use CSS + JS to show/hide what you need:
What I normally do (and your mileage may vary depending on what you need to show/hide) is this:
<html>
<head>
... other stuff here, title, meta, etc ...
<script type="text/javascript">document.documentElement.className += " js"</script>
... everything else
</head>
Then you can use CSS to hide/show based on if JavaScript is enabled/disabled:
/* Hide by default, show if JS is enabled */
#needsJS { display: none }
.js #needsJS { display: block }
/* Show by default, hide if JS is enabled */
.js #fallback { display: none }
It can't do it directly, and workarounds for it are usually awkward and wasteful.
Use progressive enhancement technique instead.
Just make the website working without JS. If everything is fine, you can attach JS functionality with e.g. jQuery.
This is also called unobtrusive JavaScript.
So you basically don't distinguish between client with JS and client without JS. You don't provide different output. You set up your HTML code in such a way that you can easily identify the elements that should JS functionality an this functionality in a programmatic way.
This way is even easier for you as you don't have to think about different outputs and it guarantees that the site is also working without JS.