We just updated portions of our website with AngularJS - particularly the login page. When I look at the search results in Google, the cached page and the small snippet it displays automatically is the raw Angular markup. So, lots of {{model.username}}, {{model.errorMessage}}, etc.
I won't link the results since it's too embarrassing.
Any idea of how do get Google to actually store the page as rendered vs. the raw HTML?
It would be wonderful if you would convert your embarrassment into a community service for all of us by testing something, since you are seeing a condition few people admit to or want to reproduce themselves. :)
Google is known to be relatively (or very, depending on who you ask) good at ignoring hidden content. They implemented this way back when people used to keyword-stuff content by using blocks that were either set to "display: none" or had a tiny/unreadable/white-on-white font.
What you're seeing is a problem for more than just SEO, so I'm suggesting this because things like prerender.io are great but they only solve that one piece. What about users who simply have slow browsers? Well, it turns out Angular has a great solution for this called ngCloak. It hides things like template content fields (ngModel mappings and bindings, expressions, etc) until Angular is ready to fill them in itself.
It's very easy to implement this; you just need a small block of CSS (in an early-loaded file, or embedded directly into your HTML page):
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
and then you apply the ngCloak directive to items that are affected, or to a high-level parent (like your ng-view DIV):
<div id="wrapper" ng-cloak>
<!-- Page content here -->
</div>
This works kind of like a no-js target, but specifically for AngularJS.
You'll still want something specific to give Google that is actually good material, but at least with the above you can filter out everything else.
SEO for angular is a really big question/issue depending on your perspective. I would start by reading http://www.ng-newsletter.com/posts/serious-angular-seo.html and http://www.yearofmoo.com/2012/11/angularjs-and-seo.html to get you started.
To sum up your primary options:
change your routing system to use the hashbang (#!). Then sites like google and facebook will convert the hashbang to _escaped_fragment_ before querying your page. This gives your server an opportunity to return different html.
use a service like http://prerender.io which will pre render and cache rendered versions of your site for you, which will be provided to google in place of your site.
There are still issues with things like sharing to reddit and stumbleupon for example, as they are lazy and don't want to develop to cater to angular based sites. So for certain circumstances you will have to get creative.
Update: One thing we have done on a recent project is look at the various user agents to determine if crawling systems are asking for page information. This way we can serve what ever we like.
Related
I'm working on a page that has to run on an embedded android system (in the system webview), and this thing is tragically slow. So slow in fact, that when you load a page, somtimes the model text is still on the page for a good half second before AngularJS gets around to updating all of the bindings. This is annoying and clearly undesirable.
I've added ng-cloak to endless permutations of elements of the page. I've also added the following style to the style sheet:
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
It just doesn't want to cloak the contents, and I think ionic is to blame. Not knowing a lot about AngularJS, I tried writing a directive my-cloak that added a class to the element on compile and pre-link and removed it on post link. It worked better, but it didn't work always.
I've read about some more things I could do like "decorating" the interpolation function (getting out of my depth) and maybe one of the various suggestions listed here (like evalAsync or something like that) but I don't know enough about Angular to understand what those solutions actually do. Coming from a jQuery background is very hard when transitioning to AngularJS.
So any help would be really appreciated. I just want to prevent the undigested text from ever showing on the screen, basically doing what ng-cloak is supposed to do but for slower systems. Thanks!
This is not an answer you are looking for, but there is a good practice to write
<span ng-bind="data"> </span>
(so no {{data}} blinking).
ng-cloak styles already on the page. Look in the header of rendered page with angular app.
you can do something like:
<body ng-show="loaded"></body> and set scope.loaded = true in controller, after data is loaded.
We run a Ruby on Rails 3.2 web application that uses a standard mix of rails and jquery.
Recently, we noticed a strange div element appearing in our production code. It seems to only show up when we render views with strings that also contain hyperlinks.
Here's an example:
We have a string in our view, that we want rendered as HTML:
"Try to search <a href='/search?q=hiring'>hiring</a>"
When we render the page in production though, we get the following:
"Try to search <a href="azarvuttcexyytzq.html" id="qqqqtra" rel="file">trufarwdstrzyzdyw</div>."
We're not sure why but the following div is being appended to our link:
<div style="display: none;">trufarwdstrzyzdyw</div>
What's strange is that we don't think that the file azarvuttcexyytzq.html exists on our servers, and we also found out that "file" is not an acceptable rel value for a hyperlink's relation attribute.
So, where could the div be coming from?
One thought is that it is coming from some analytics library in our system, since we're using Google Analytics. But we can't seem to confirm that idea or rule it out.
Does anyone know of a library that causes behavior like this?
Any help or insight would be appreciated.
If there is no developer who has done this (intentionally or otherwise) by appending a div with a random hyperlink in your application, then there is a high probability that your application server, some library or a gem you are using is compromised. It would be good to do an audit of your code/server and ensure that you are using the original version of all the gems and libraries and no malicious code is otherwise included in your app code.
We had the exact same issue, although intermittently, and it was Distil networks injecting in our case. To verify we took Distil out for the site and it worked like a charm!
Although, have yet to find how to get it working with Distil, will update the answer if/when we do
We had the same issue, our application behind Distil as well as in other comments.
If you use Distil, read this:
https://help.distilnetworks.com/hc/en-us/articles/235705127-Optimizing-Honeypot-Links-for-Pages-with-Inline-JavaScript
In short: Add the following comment near the top of your page (and above the JS) to force Distil injection to happen there: </a> -–> You can also add any other custom, a unique comment which Distil could use to inject the honeypot link code into.
I have a search plugin that is more like a filter within a page (it's Swiftfilter and isotope filter). But I want the search to include all the pages on my website.
For example :
I am doing a travel website. When people search on index.html for "Italy". I want the search result directly link to italy.html page.
How can I do that?
What does this call?
Where can I learn/get this plugin?
Can swiftfilter or isotope filter enhance this?
Your problem can get a bit complicated. I'm afraid it's not a simple as finding a single plugin that can do this. It sounds to me like you have a static website, where content is stored across different, hard-coded pages. A static website can get complicated because number one, it would be slow/clunky to search hard-coded files on a website. Number two, you would have to deal with caching systems to speed it up.
If you want to implement a search feature, I suggest that you have a template-driven/database enabled website instead. Why don't you consider moving your site and all its pages over to something like Wordpress?
All your pages would get stored in a database and WP already has its own built-in search functionality. It works really well and I think you should consider it if you have a lot of pages on your website.
I'm trying to load a "webpage" using the Android WebView but the images won't load. Firstly, I retrieve a text String that's formatted in Markdown. Afterwards, I convert the Markdown into HTML using Markdown4J, and then using the Android WebView's loadDataWithBaseUrl() function, I load the WebView with the html.
String html = null;
try {
html = new Markdown4jProcessor().process(mText);
} catch (IOException e) {
e.printStackTrace();
}
String css = "<link rel=\"stylesheet\" type=\"text/css\" href=\"blogstyle.css\" />";
final String htmlData = css + html;
body.loadDataWithBaseURL("file:///android_asset/", htmlData, "text/html", "UTF-8", null);
Everything in the webview displays and is formatted properly except the images. The images just won't show, and there are definitely image tags inside of the HTML, such as
<img src="https://www.random.org/analysis/randbitmap-rdo.png">
And I have no idea why my WebView wouldn't be able to display this image?
EDIT: The internet permissions in the manifest is already requested. And here is an example of a sample markdown string. I then convert this line into HTML.
"One of the huge problems today with web development is that it isn’t modular; because of how CSS and HTML work, it’s extremely difficult to just drag and drop an element from one site into another without some very strange side-effects. Shape and size can be different, resources can fail to load based on relative paths, and you have to import at least a .html, .css and .js file for each element. Even with all that, there’s no guarantee you won’t have CSS or JavaScript collisions.\n\n \n\nThe solution to this problem? [**Web Components**](http://webcomponents.org/). Now you should know up front that Web Components don’t work in IE and Safari, but they *are* under development.\n\n \n\nSo, what are web components? Well, essentially, they are plug-n-play modules for the web. The picture here is actually a great example. If you’re familiar with web design, imagine how long this would take to make, even statically. You’d have to position the images, set the roundness, give a height to the three main elements, set the font colors… Basically, it’d take you more than five minutes to get this up-and-running.\n\n![blog-image](https://www.ruralsourcing.com/wp-content/uploads/2014/09/blog-image-265x300.png)\n\nSo what if I told you *all the code for what you see is two lines?* Just these two:\n\n \n\n\n <linkref=\"import\"href=\"gitcard.html\">\n <github-carduser=\"nasawa\">\n\n\nAnd that’s all. Just import the html and use the custom element! Using a new templating system called *Shadow DOM*, the browser holds a template called *github-card* with encapsulated styles and JavaScript. This way, even if you have elements named the same, there will never be any collision. And of course, you can have the *github-card* tag wherever you want, as many times as you want, and data will not transfer over.\n\n \n\nOn the other end, if you’re creating a web component, you can easily add as many customizable fields as you want to allow the user to modify your component at specific spots. For example, this is what the simplified Google Maps component looks like:\n\n \n\n\n`<google-mapslatitude=\"30.686603\"longitude=\"-88.046224\"></google-maps>`\n \n\nAnd a complicated Google Maps component looks like this:\n\n\n <google-maplatitude=\"37.77493\"longitude=\"-122.41942\"fitToMarkers>\n <google-map-markerlatitude=\"37.779\"longitude=\"-122.3892\"\n draggable=\"true\"title=\"Go Giants!\"></google-map-marker>\n <google-map-markerlatitude=\"37.777\"longitude=\"-122.38911\"></google-map-marker>\n </google-map>\n\n\n \n\nAs you can see, it is truly a great time to be in web development. Complex procedures are getting better and easier every day as we push closer to a true implementation of HTML5 and a unified multiplatform experience, and web components are a spearhead on that advancement. Look out for the next big thing – it’ll be here before you know it!\n\n \n\nChristopher Johnson \n Jr. Associate Programmer"
which would give me the following in HTML:
<p>"One of the huge problems today with web development is that it isn’t modular; because of how CSS and HTML work, it’s extremely difficult to just drag and drop an element from one site into another without some very strange side-effects. Shape and size can be different, resources can fail to load based on relative paths, and you have to import at least a .html, .css and .js file for each element. Even with all that, there’s no guarantee you won’t have CSS or JavaScript collisions.</p>
<p> </p>
<p>The solution to this problem? <strong>Web Components</strong>. Now you should know up front that Web Components don’t work in IE and Safari, but they <em>are</em> under development.</p>
<p> </p>
<p>So, what are web components? Well, essentially, they are plug-n-play modules for the web. The picture here is actually a great example. If you’re familiar with web design, imagine how long this would take to make, even statically. You’d have to position the images, set the roundness, give a height to the three main elements, set the font colors… Basically, it’d take you more than five minutes to get this up-and-running.</p>
<p><img src="https://www.ruralsourcing.com/wp-content/uploads/2014/09/blog-image-265x300.png" alt="blog-image" title="" /></p>
<p>So what if I told you <em>all the code for what you see is two lines?</em> Just these two:</p>
<p> </p>
<pre><code><linkref=\"import\"href=\"gitcard.html\">
<github-carduser=\"nasawa\">
</code></pre>
<p>And that’s all. Just import the html and use the custom element! Using a new templating system called <em>Shadow DOM</em>, the browser holds a template called <em>github-card</em> with encapsulated styles and JavaScript. This way, even if you have elements named the same, there will never be any collision. And of course, you can have the <em>github-card</em> tag wherever you want, as many times as you want, and data will not transfer over.</p>
<p> </p>
<p>On the other end, if you’re creating a web component, you can easily add as many customizable fields as you want to allow the user to modify your component at specific spots. For example, this is what the simplified Google Maps component looks like:</p>
<p> </p>
<p><code><google-mapslatitude=\"30.686603\"longitude=\"-88.046224\"></google-maps></code>
</p>
<p>And a complicated Google Maps component looks like this:</p>
<pre><code><google-maplatitude=\"37.77493\"longitude=\"-122.41942\"fitToMarkers>
<google-map-markerlatitude=\"37.779\"longitude=\"-122.3892\"
draggable=\"true\"title=\"Go Giants!\"></google-map-marker>
<google-map-markerlatitude=\"37.777\"longitude=\"-122.38911\"></google-map-marker>
</google-map>
</code></pre>
<p> </p>
<p>As you can see, it is truly a great time to be in web development. Complex procedures are getting better and easier every day as we push closer to a true implementation of HTML5 and a unified multiplatform experience, and web components are a spearhead on that advancement. Look out for the next big thing – it’ll be here before you know it!</p>
<p> </p>
<p>Christopher Johnson <br />
Jr. Associate Programmer"</p>
I know, I should have built this in a progressive enhancement way instead of trying to gracefully degrade. But I didn't. So now I need a way to make this work, preferably without altering the structure too much.
What I need is, if they don't have javascript enabled, then it will reload the page and add a hash tag. Based on that hash tag I wish to load different data into a spot.
I am using Drupal and this is dynamic content and there are hundreds of pages. I can change the markup easily across all of them from the template... it's just a very basic implementation of Organic tabs, but with variables in place of the tab titles and bodies.
Based on my research, I would think this has to be done manually (with separate pages that "look" like tabs), but I know that is not the case as I have seen this functionality here: http://observers.gohernandez.com/election/results/2005/kabul With the quicktabs module.
Thanks very much in advance.
I found, after sifting through literally hundreds of tabs plugins, this one that actually degrades gracefully: http://blog.ginader.de/archives/2009/02/07/jQuery-Accessible-Tabs-How-to-make-tabs-REALLY-accessible.php