Strategy for making React image gallery SEO-friendly - javascript

I wrote a React image gallery or slideshow. I need to make the alt text indexable by search engines, but because my server is in PHP, React.renderToString is of limited use.
The server is in PHP + MySQL. The PHP uses Smarty, a decent PHP template engine, to render the HTML. The rest of the PHP framework is my own. The Smarty template has this single ungainly line:
<script>
var GalleryData = {$gallery};
</script>
which is rendered by the PHP's controller function as follows:
return array(
'gallery' => json_encode($gallery),
);
($gallery being the result table of a MySQL query).
And my .js:
React.render(<Gallery gallery={GalleryData} />, $('.gallery').get(0));
Not the most elegant setup, but given that my server is in PHP there doesn't seem to be much of a better way to do it (?)
I did a super quick hack to fix this at first shot - I copied the rendered HTML from Firebug, and manually inserted it into a new table in the DB. I then simply render this blob of code from PHP and we're good to go on the browser.
There was one complication which is that because React components are only inserted into the DOM as they're first rendered (as I understand it), and because the gallery only shows one image slide at a time, I had to manually click through all slides once before saving the HTML code out.
Now however the alt text is editable by CMS and so I need to automate this process, or come up with a better solution.
Rewriting the server in Node.js is out of the question.
My first guess is that I need to install Node, and write a script that creates the same React component. Because the input data (including the alt text) has to come from MySQL, I have a few choices:
connect to the MySQL DB from Note, and replicate the query
create a response URL on the PHP side that returns only the JSON (putting the SQL query into a common function)
fetch the entire page in Node but extracting GalleryData will be a mess
I then have to ensure that all components are rendered into the DOM, so I can script that by manually calling the nextSlide() method as many times as there are slides (less one).
Finally I'll save the rendered DOM into the DB again (so the Node script will require a MySQL connection after all - maybe the 1st option is the best).
This whole process seems very complicated for such a basic requirement. Am I missing something?
I'm completely new to Node and the whole idea of building a DOM outside of the browser is basically new to me. I don't mind introducing Node into my architecture but it will only be to support React being used on the front-end.
Note that the website has about 15,000 pageviews a month, so massive scalability isn't a consideration - I don't use any page caching as it simply isn't needed for this volume of traffic.
I'm likely to have a few React components that need to be rendered statically like this, but maintaining a small technical overhead (e.g. maintaing a set of parallel SQL queries in Node) won't be a big problem.
Can anyone guide me here?

I think you should try rendering React components on server-side using PHP. Here is a PHP lib to do that.
But, yes, you'll basically need to use V8js from your PHP code. However, it's kind of experimental and you may need to use other around. (And this "other way around" may be using Node/Express to render your component. Here is some thoughts on how to do it.)

Related

Is there a way to get current HTML from browser in Python?

I am currently working on a HTML presentation, that works well, but I need the presentation to be followed simultaneously with a NAO robot who reads a special html tag. I somehow need to let him know, which slide I am on, so that he can choose the correct tag.
I use Beautiful Soup for scraping the HTML, but it does so from a file and not from a browser. The problem is, there is javascript running behind, assigning various classes to specific slides, that tell the current state of the presentation. And I need to be able to access those, but in the default state of the presentation they are not present and are added asynchronously throughout the process of the presentation.
Hopefully, my request is clear.
Thank you for your time
http://www.seleniumhq.org/ (probably webdriver) is your friend. Initialize a browser and call browser.html to get the document in the current state.
There's wget on the robot, you could use it... (though I'm not sure I understand where is really the problem...)

Generating HTML in JavaScript vs loading HTML file

Currently I am creating a website which is completely JS driven. I don't use any HTML pages at all (except index page). Every query returns JSON and then I generate HTML inside JavaScript and insert into the DOM. Are there any disadvantages of doing this instead of creating HTML file with layout structure, then loading this file into the DOM and changing elements with new data from JSON?
EDIT:
All of my pages are loaded with AJAX calls. But I have a structure like this:
<nav></nav>
<div id="content"></div>
<footer></footer>
Basically, I never change nav or footer elements, they are only loaded once, when loading index.html file. Then on every page click I send an AJAX call to the server, it returns data in JSON and I generate HTML code with jQuery and insert like this $('#content').html(content);
Creating separate HTML files, and then for example using $('#someID').html(newContent) to change every element with JSON data, will use even more code and I will need 1 more request to server to load this file, so I thought I could just generate it in browser.
EDIT2:
SEO is not very important, because my website requires logging in so I will create all meta tags in index.html file.
In general, it's a nice way of doing things. I assume that you're updating the page with AJAX each time (although you didn't say that).
There are some things to look out for. If you always have the same URL, then your users can't come back to the same page. And they can't send links to their friends. To deal with this, you can use history.pushState() to update the URL without reloading the page.
Also, if you're sending more than one request per page and you don't have an HTML structure waiting for them, you may get them back in a different order each time. It's not a problem, just something to be aware of.
Returning HTML from the AJAX is a bad idea. It means that when you want to change the layout of the page, you need to edit all of your files. If you're returning JSON, it's much easier to make changes in one place.
One thing that definitly matters :
How long will it take you to develop a new system that will send data as JSON + code the JS required to inject it as HTML into the page ?
How long will it take to just return HTML ? And how long if you can re-use some of your already existing server-side code ?
and check how much is the server side interrection of your pages...
also some advantages of creating pure HTML :
1) It's simple markup, and often just as compact or actually more compact than JSON.
2) It's less error prone cause all you're getting is markup, and no code.
3) It will be faster to program in most cases cause you won't have to write code separately for the client end.
4) The HTML is the content, the JavaScript is the behavior. You're mixing both for absolutely no compelling reason.
in javascript or nay other scripting language .. if you encountered a problem in between the rest of the code will not work
and also it is easier to debug in pure html pages
my opinion ... use scriptiong code wherever necessary .. rest of the code you can do in html ...
it will save the triptime of going to server then fetch the data and then displaying it again.
Keep point No. 4 in your mind while coding.
I think that you can consider 3 methods:
Sending only JSON to the client and rendering according to a template (i.e.
handlerbar.js)
Creating the pages from the server-side, usually faster rendering also you can cache the page.
Or a mixture of this would be to generate partial views from the server and sending them to the client, for example it's like having a handlebar template on the client and applying the data from the JSON, but only having the same template on the server-side and rendering it on the server and sending it to the client in the final format, on the client you can just replace the partial views.
Also some things to think about determined by the use case of the applicaton, is that if you are targeting SEO you should consider ColBeseder advice, of if you are targeting mobile users, probably you would better go with the JSON only response, as this is a more lightweight response.
EDIT:
According to what you said you are creating a single page application, if this is correct, then probably you can go with either the JSON or a partial views like AngularJS has. But if your server-side logic is written to handle only JSON response, then probably you could better use a template engine on the client like handlerbar.js, underscore, or jquery templates, and you can define reusable portions of your HTML and apply to it the data from the JSON.
If you cared about SEO you'd want the HTML there at page load, which is closer to your second strategy than your first.
Update May 2014: Google claims to be getting better at executing Javascript: http://googlewebmastercentral.blogspot.com/2014/05/understanding-web-pages-better.html Still unclear what works and what does not.
Further updates probably belong here: Do Google or other search engines execute JavaScript?

Website Usage Tracking with Colfusion/JavaScript/Other

Our website development team manages many web sites (each with a different vanity URL) on our INTRAnet. We'd like to implement something (code snippet) that is easy to add the Application.cfm/OnRequestEnd.cfm page which would insert a record into the database tracking things like page, url, querystring, userid, etc - basic stuff. Inserting the record is not a big deal. What I'd like to know is from a performance stand point, what would you all recommend so that we dont' get a bottleneck of inserts queued up as employees hit the various sites. We can't use jQuery since not every site will have the same version of jQuery so we really are limited to just using Coldfusion - I think.
Ideally, what we'd like to be able to do is create one main tracking file on our main server and reference that file from all of our other sites. Then if/when we need to make an update, we can make a global change - kind of like how Google Analytics does, just not nearly as much details.
On all of the sites we support, we do have our department logo on those pages. I thought about building a tracking process into the loading of the image, much like they do with emails.
Any thoughts on this would be appreciated of if you have a better idea - I'm all ears.
UPDATED
Regarding the image processing, I could not find the original link for the tutorial from easycfm.com but I found what appears to be the identical code here: http://www.experts-exchange.com/Software/Server_Software/Web_Servers/ColdFusion/A_2386-Track-your-Emails-using-coldfusion.html
I would say that you should not try to prematurely optimise this until you have a reason to. If you find you have a problem down the track, you can deal with it then.
Create a Logging CFC and implement a method which receives the metrics you wish to log, and then wraps that up into a record to insert into the DB, and use <cfquery> to write them to a DB table. Call the function from OnRequestEnd.cfm.
I specifically suggest rolling this into a Logging CFC because if you need to change the implementation of how you log things later on, you can just change the inner workings of the logging method, instead of having to mess with all your sites.
Adam Cameron's answer is probably the way you should go. On top of that what I would suggest is inserting those records into a table with no additional indexes. This will cause the inserts to be very quick. Then you can use a scheduled database job to move this data into a nice normalised schema that is quick to analyse.
I wouldn't write off using JavaScript just because each site will have a different version of JQuery. People still used to be able to get stuff done prior to the existence of JQuery it is just a JavaScript library. It is very basic JavaScript to include dynamically include a script file that points at your tracking file with the relevant parameters.
<script type="text/javascript">
var script = document.createElement("script");
var body = document.getElementsByTagName("body")[0];
script.setAttribute("src", "http://www.yourdomain.com/trackingfile.cfm?" + yourparams);
body.appendChild(script);
</script>
As you can see, no need for JQuery.

HTML that's both server-side and javascript generated - how to combine?

I'm usually a creative gal, but right now I just can't find any good solution. There's HTML (say form rows or table rows) that's both generated javascript-based and server-sided, it's exactly the same in both cases. It's generated server-sided when you open the page (and it has to stay server-sided for Google) and it's generated by AJAX, to show live updates or to extend the form by new, empty rows.
Problem is: The HTML generation routines are existing twice now, and you know DRY (don't repeat yourself), aye? Each time something's changed I have to edit 2 places and this just doesn't fit my idea of good software.
What's your best strategy to combine the javascript-based and server-sided HTML generation?
PS: Server-sided language is always different (PHP, RoR, C++).
PPS: Please don't give me an answer for Node.JS, I could figure that out on my own ;-)
Here's the Ruby on Rails solution:
Every model has its own partial. For example, if you have models Post and Comment, you would have _post.html.erb and _comment.html.erb
When you call "render #post" or "render #comment", RoR will look at the type of the object and decide which partial to use.
This means that you can redner out an object in the same way in many different views.
I.e. in a normal response or in an AJAX response you'd always just call "render #post"
Edit:
If you would like to render things in JS without connecting to the server (e.g. you get your data from a different server or whatever), you can make a JS template with the method I mentioned, send it to the client and then have the client render new objects using that template.
See this like for a JS templating plugin: http://api.jquery.com/category/plugins/templates/
Make a server handler to generate the HTML. Call that code from the server when you open the page, and when you need to do a live update, do an AJAX request to that handler so you don't have to repeat the code in the client.
What's your best strategy to combine the javascript-based and server-sided HTML generation?
If you want to stay DRY, don't try to combine them. Stick with generating the HTML only on the server (clearly the preferable option for SEO), or only on the client.
Make a page which generates the HTML on the server and returns it, e.g.:
http://example.com/serverstuff/generaterows?x=0&y=foo
If you need it on the server, access that link, or call the subroutine that accessing the link calls. If you need it on the client, access that link with AJAX, which will end up calling the same server code.
Or am I missing something? (I'm not sure what you mean by "generated by AJAX").
I don't see another solution if you have two different languages. Either you have a PHP/RoR/whatever to JavaScript compiler (so you have source written in one language and automatically generated in the others), or you have one generate output that the other reads in.
Load the page without any rows/data.
And then run your Ajax routines to fetch the data first time on page load
and then subsequently fetch updates/new records as and when required/as decided by your code.

What is the best approach for handling a complex form in html?

I need to implement a webform (JSP, struts) featuring loads of checkboxes and textfields. Basically I have a tree made of checkboxes which has to be extendable (like adding a new node). On another page the same data is used, but refined. So you add again child nodes to the mentioned data structure using textboxes etc. I can describe the datastructure in XML:
But contains about 100 rows in reality.
I found 3 approaches:
1. Do a webform in JSP which lowers the user experience because lots of postbacks are necessary (every time i add/edit/delete a node, subnode...)
2. do it in async fashion. -> loads of javascript to handle the structure of the data (keep the XML data in a hidden div and update ui)
3. go for a RIA like OpenLaszlo
What do you suggest?
If you already know OpenLaszlo, go for it. You will end up with a better user experience with less work.
You should target user interface and performance when developing an app. So IMO, plain JSP will be my last approach.
You can consider client side rendering.It allows to build very responsive web apps:
build your JSP pages to deliver JSON data, no HTML here
use a javascript templating engine in the browser to convert the data in HTML client side. I'm the author of PURE but there are plenty of others on the web that may suit better your style
when the user types or press submit, parse the form using a common technique found in many frameworks. i.e: the "name" attribute is the path to set the value in the JSON<input name="employee.name" type="text" ... />
When the form is parsed, post back the JSON to a JSP page that will read it and do the backend work.
You can use XML instead of JSON and XSLT instead of a JS templating engine, but if you target the web browser only, it adds an extra layer of complexity and trouble to parse the XML.

Categories