Close

Visualizing data in a React app with Vaadin Charts 3.2

Vaadin Charts 3.2 is here. With the latest release, we continue to cater to the newest client-side libraries. The new version brings you improved integration to the React JavaScript library. Before the version 3.2 you were able to use Vaadin Charts in React, but you had to write a bit more boilerplate code than we were comfortable with. Now the integration is a lot smoother.

Sample charts screenshot

I’ll cover the five simple steps you need to take to get Vaadin Charts into use in your React application. I assume you are using Browserify (and npm). If you don’t have such a React project at hand, you can use one from here https://github.com/samiheikki/react-starter-kit

1. Install the Vaadin Charts dependency with Bower

bower install --save vaadin-charts

2. Add Web Components polyfill to your index.html to be able to use HTML imports

<script src="bower_components/webcomponentsjs/
    webcomponents-lite.min.js">

3. Import your choice of a chart type

<link rel="import" href="bower_components/vaadin-charts/
    vaadin-pie-chart.html">

4. In your index.js import the Vaadin Charts component before React

// Must be imported before React
require('./bower_components/vaadin-charts/react');
var React = require('react');
var ReactDOM = require('react-dom');

There is an additional step involved if you are using Webpack, it’s described here in Vaadin Docs.

5. Configure your chart and its data series in the render function using the declarative Elements API.

var MyPie= React.createClass({
  getDefaultProps: function() {
    return {
      data: []
    };
  },
  render: function() {
    return (
      <vaadin-pie-chart>
        <title>My First</title>
        <subtitle>Pie Chart</subtitle>
      <data-series name="My data">
        <data>{this.props.data.map(JSON.stringify).join(',')}</data>
      </data-series>
    </vaadin-pie-chart>
    )
  }
});

ReactDOM.render(
  // e.g. [["Hey", 1], ["What's", 2], ["Going", 3], ["On", 0.5]]
  <MyPie data={getMyExampleChartJSONData()}/>,
  document.getElementById('example')
);

Take a look at more detailed usage examples in the reference documentation of Vaadin Charts in Vaadin Docs. See all the chart types and a lot of the features in action, visit the Vaadin Charts demo site at http://demo.vaadin.com/vaadin-charts/.

We are Vaadin - Sebastian from the Vaadin Berlin office

Sebastian works at the Vaadin office in Berlin and is currently occupied with some upcoming new products and proof of concepting them. He joined Vaadin in the beginning of March, so only 5 months in the company and already working in Vaadin projects at full speed.

Q. What did you do before Vaadin? 
I worked as an IT-consultant in Germany for a couple of years and mostly did projects in the area of financial services. Before that I finished my studies of Computer Science in Berlin and tried to spend as much time as possible abroad and face intercultural challenges. 

Q. Why did you decide to join Vaadin?
During my studies I came in touch with Vaadin for a small web-application and I was very excited about the technology, with how little effort I could create a proper and good looking website, and the exchange in the community. When Vaadin decided to open an office in Berlin, I instantly wanted to join the Vaadin team and work with the newest technology trends at the market.

Q. What’s it like working in Vaadin’s Berlin office with Finnish and US colleagues?
There are challenges, we are in different time zones and locations. However, we overcome this with using modern technologies to communicate and share ideas. For example, to create technical concepts or plan projects, we are using different web applications that anyone can access. This is the perfect basis to provide an overview or discuss ideas over the distance. In this way, we are exchanging and sharing a lot of ideas with our colleagues every day, and the Vaadin team members are travelling between offices regularly which is great in my opinion.

Q. What has been the most surprising thing?
How free I actually am in choosing my way of working - we have been given the freedom to use the best possible tool to succeed in our job. That is really cool - there is trust among colleagues and the team. The other point that I am surprised by is that for the most part Vaadin people fit very well together - so it does not matter in which location, nationality or gender you are.

Q. What makes this a great workplace?
The free choice of hardware and equipment, new projects are offered by asking us ‘what would you like to do ?’, and our own strengths are used in the best possible way. I have the possibility to influence on my own job. That is great!

Q. What do you do in your freetime and does it help your work somehow?
I do a lot of sports, e.g. cross-fit and badminton with colleagues, since we sit a lot in our work, the software business is like that by nature. In addition, I love to travel - it is really good to get different points of view on cultures and also to relax. Travel experiences help when we have diverse customers from diverse/different countries - it helps to communicate and understand them better.

Q. What would you say is the #1 reason for working at Vaadin?
Because of the amazing people! It is really the mostly the great team behind the technology, we are all for all (not for one), super team work is the key success factor. The environment is open for discussion and opinions - we share our common challenges and try to solve them together, really.

 

Adventures in SEO

TL;DR: Vaadin was hardly SEO-friendly in the past. Not anymore, with the new Volga library.

Bookmarking pages

Bookmarking is as old as www itself. Being able to save an URL is part of the ADN of websites. Regarding web apps, this is somewhat different. For example, in an e-commerce webapp, while it does make sense to bookmark a specific product, bookmarking a specific step of the checkout process does not.

Following the shop example, here’s what happens in a traditional servlet-based context:

  1. A servlet is mapped on a specific subcontext such as /product/*
  2. When the URL /product/really-cool-product is called, the doGet() method of that servlet is called
  3. The method parses the URL to read the really-cool-product part - which should be an unique key for the product
  4. It delegates to a whole chain of components that loads the product from the datastore
  5. It forwards to a JSP along with the relevant product data
  6. This JSP generates the HTML

Single-Page Applications

Come SPAs. By definition, they serve all content under the same URL. This makes bookmarking specific pages of the application impossible because there are no pages per se. In general, SPAs handle this problem with fragment identifiers. The above URL becomes /product#really-cool-product, problem solved. In Vaadin, this directly translate to usage of the Page.getCurrent().setUriFragment() method or of the Navigator API.

Unfortunately, this doesn’t work at all with the crawling part of SEO. Fragments are not discriminatory parts of an URL: #really-cool-product and #another-cool-product do point to the same URL so bots such as Google Bot won’t crawl both.

The fragment identifier functions differently than the rest of the URI: namely, its processing is exclusively client-side with no participation from the web server. 
-- Wikipedia

 

For a while Google recommended to use special “hashbang” style URLs (#!my-indexable-view), like what Navigator in Vaadin uses, and specially served SEO material for those views, but this was a tricky workaround and the approach is now deprecated by Google as well.

Distinct URLs for SPAs

Back to square one, both /product/really-cool-product and /product/another-cool-product paths are required. This problem is not unique to Vaadin, but common to all server- and client-side SPA frameworks. What is required is:

  1. To have the client change the browser’s URL without full page reload
  2. To have the server handle paths

In JavaScript, the answer is to use the History API. I assume everyone is familiar with the following snippet:

window.back();
window.go(-1);

This is however absolutely not standard. This should be replaced by the following:

window.history.back();
window.history.go(-1);

The history object implements the History API. It’s supported by all modern browsers. In particular, the API makes it possible to add entries in the browser history via thepushState() method, without actually doing full page loads.

Suppose http://mozilla.org/foo.html executes the following JavaScript:
var stateObj = { foo: "bar" };
history.pushState(stateObj, "page 2", "bar.html");
This will cause the URL bar to display http://mozilla.org/bar.html, but won't cause the browser to load bar.html or even check that bar.html exists.
--Mozilla Developer Network

Note that Vaadin Directory contains the History wrapper library around the client-side API. It provides a way to manage the history object from server-side Vaadin code.

On the server-side, paths also need to be handled. In Vaadin apps, full URLs are accessible in UI.init() methods, from servlets or from e.g. BootstrapListeners. The History add-on also supports the Navigator API and View objects with full paths without hashbang-style URLs.

Beyond distinct URLs

Distinct URLs is only the emerged part of the iceberg regarding SEO.

One wants to have dedicated meta headers for each dedicated URL, such as <title> and <meta name="description">. Even further, social medias have their own dedicated meta headers, e.g.:

Volga, the SEO-friendly Vaadin library

Implementing the steps above from scratch in your Vaadin project is definitely not trivial. Rejoice, for comes Volga, a ready-to-use library that handles the brunt of things for you.

To use it, just add this snippet to your POM:

<dependency>
    <groupId>org.vaadin</groupId>
    <artifactId>volga</artifactId>
    <version>0.1</version>
</dependency>

Important part of the API include:

org.vaadin.volga.VolgaDetails
Holds a set of metadata headers
org.vaadin.volga.VolgaServlet
Set the VolgaDetails for the root path and provides bindings between a path and other VolgaDetails objects. This way, each specific path can be set their own VolgaDetails.
org.vaadin.volga.Volga
Holds the previously defined mappings
org.vaadin.volga.VolgaUI
Handles the initial configuration
org.vaadin.volga.SeoBootstrapListener
Fills page metadata headers from a VolgaDetails object

For more details, please check this example project on Github. It's deployed online and here are results shown on Google search that proves that it works.

 

Demo application as seen on Google Search

This works for Twitter as well:

Twitter card for main view Twitter card for second

Miscellaneous finishing touches

There are also a couple of other tricks to consider to help bots crawl Vaadin apps.

  • Use a robots.txt file
  • Use a sitemap.xml
  • Use basic links to navigate between views (see PushStateLink in History)
  • Use well-formed HTML, e.g. use proper <h1> elements instead of just styling headers bigger (see Header and RichText in Viritin)

Note, that GWT is currently failing to serve anything relevant for GoogleBot by default. A patch is available in Volga but it will be fixed in Vaadin itself soon

Don’t wait and make relevant parts of your app SEO-friendly with Volga now!