diff --git a/LANGS.md b/LANGS.md
index 25b60e8a..bf3ac484 100644
--- a/LANGS.md
+++ b/LANGS.md
@@ -1 +1,2 @@
 * [English](en/)
+* [Français](fr/)
diff --git a/fr/README.md b/fr/README.md
new file mode 100644
index 00000000..409ccde4
--- /dev/null
+++ b/fr/README.md
@@ -0,0 +1,52 @@
+# Guide du rendu côté serveur de Vue.js
+
+> **Note** : ce guide nécessite les versions minimales de Vue et des librairies :
+>
+> * vue & vue-server-renderer >= 2.3.0
+> * vue-router >= 2.5.0
+> * vue-loader >= 12.0.0 & vue-style-loader >= 3.0.0
+>
+> Si vous avez déjà utilisé Vue 2.2 avec le SSR, vous remarquerez que la structure de code recommandé est désormais [un peu différente](./structure.md) (avec l'option [unInNewContext](./api.md#runinnewcontext) ayant pour valeur `false`). Votre application existante devrait continuer de fonctionner, mais il est recommander de migrer vers ces nouvelles recommandations.
+
+## Qu'est-ce que le rendu côté serveur (Server-Side Rendering, SSR) ?
+
+Vue.js est un framework pour créer des applications clients. Par défaut, les composants Vue produisent et manipulent le DOM dans le navigateur. Toutefois, il est aussi possible de rendre ces mêmes composants en chaînes de caractères HTML sur le serveur, les envoyer directement au navigateur, et enfin "hydrater" le balisage statique en une application entièrement interactive sur le client.
+
+Une application Vue rendue par le serveur peut aussi être considérée comme "isomorphique" ou "universelle", dans le sens que la majorité du code de votre application fonctionnera côté serveur **et** côté client.
+
+## Pourquoi le rendu côté serveur ?
+
+Par rapport à la traditionnelle SPA (Single-Page Application, Application Page Unique), l'avantage du SSR consiste en :
+
+* Un meilleur SEO, vu que les robots des moteurs de recherche verront directement la page entièrement rendue,
+
+* Notez qu'à partir de maintenant, Google et Bing peuvent indexer les applications JavaScript synchrones. Synchrone est le mot important ici. Si votre application commence avec une image de chargement, et qu'elle récupère du contenu via Ajax, le robot ne va pas attendre que la récupération du contenu de manière asynchrone soit terminée. Ce qui veut dire que si vous avez du contenu récupéré de manière asynchrone et où le SEO est important, le SSR pourrait être nécessaire.
+
+* Un chargement plus rapide, notamment avec des appareils lents, ou une connexion internet lente. Le code HTML rendu par le serveur n'a pas besoin d'attendre que le JavaScript soit téléchargé et exécuté pour être affiché. L'utilisateur de votre application verra donc plus tôt une page entièrement rendue. Cela résulte généralement en une meilleure expérience utilisateur, et peut être critique pour des applications où le chargement est directement associé avec le taux de conversion.
+
+Il y a également quelques points négatifs à prendre en compte en utilisant le SSR :
+
+* Les contraintes de développement. Le code spécifique au navigateur ne peut être utilisé que dans certains connecteurs du cycle de vie ; certaines librairies devront recevoir un traitement spécial pour être capable de fonctionner sur une application rendue par le serveur.
+
+* Un build setup et des besoins pour le déploiement plus complexes. Au contraire d'une SPA entièrement statique qui peut être déployée sur n'importe quel serveur de fichier statique, une application rendue par le serveur a besoin d'un environnement où un serveur Node.js peut tourner.
+
+* Plus de charge pour le serveur. Faire entièrement le rendu d'une application avec Node.js sera bien évidemment plus coûteux pour le processeur, que de servir des fichiers statiques. Donc si vous vous attendez à beaucoup de trafic, préparez-vous à cette charge serveur et utilisez judicieusement des stratégies de mise en cache.
+
+Avant d'utiliser le SSR pour votre application, la première question que vous devez vous demander est si vous en avez réellement besoin. Cela dépend principalement à quel point le temps d'affichage de votre application est important ou non. Par exemple, si vous avez créé un tableau de bord interne à votre application, et où attendre quelques centaines de millisecondes en plus n'est pas vraiment un problème, il serait exagéré d'utiliser le SSR. Cependant, dans les cas où le chargement et le rendu de la page est un point critique, le SSR peut vous aider à atteindre les meilleures performances possibles pour le chargement initial de votre application.
+
+## SSR vs pré-rendu
+
+Si vous n'êtes seulement intéressé par le SSR uniquement pour améliorer le SEO et une poignée de pages (ex: `/` ,  `/about` , `/contact`, etc...), alors c'est probablement  que vous vous intéressez au **pré-rendu**. Au lieu d'utiliser un serveur web pour compiler du HTML à la volée, le pré-rendu génère des fichiers HTML pour des routes spécifiques, au moment de la compilation. L'avantage du pré-rendu est qu'il est beaucoup plus simple à mettre en place, et qu'il vous permet de garder votre _front-end_ entièrement statique.
+
+Si vous utilisez Webpack, il est alors possible d'ajouter facilement le pré-rendu avec [prerender-spa-plugin](https://github.com/chrisvfritz/prerender-spa-plugin). Il a été largement testé avec les applications Vue - et en fait, le créateur est un membre de l'équipe principale de Vue.
+
+## A propos de ce guide
+
+Ce guide se concentre sur les SPA rendues par un serveur Node.js. Mélanger le SSR de Vue avec d'autres configurations _backend_ est un sujet à part entière, et ne sera pas pas couvert dans ce guide.
+
+Ce guide sera très approfondi, il est donc nécessaire d'être familier avec Vue.js, et d'avoir une connaissance décente de Node.js et webpack. Si vous préférez une solution plus avancée et qui offre une meilleure expérience d'utilisation _out-of-the-box_, vous devriez essayer [Nuxt.js](https://nuxtjs.org/). Nuxt.js est construit sur le même _Vue stack_, mais elle abstrait énormément la structure de base de l'application. Elle apporte cependant quelques fonctionnalités supplémentaires, comme la génération de site statique par exemple. Toutefois, il se peut que cela ne convienne pas à votre utilisation si vous avez besoin de plus de contrôle sur la structure de votre application. Quoi qu'il en soit, il serait toujours utile de lire ce guide pour mieux comprendre son fonctionnement.
+
+Comme vous lisez, il serait utile de se référer à la [démo HackerNews ](https://github.com/vuejs/vue-hackernews-2.0/) officielle, qui utilise la plupart des techniques couvertes dans ce guide.
+
+Enfin, notez que les solutions dans ce guide ne sont pas définitives - nous avons trouvées qu'elles fonctionnaient bien pour nous, mais cela ne veut pas dire qu'elles ne peuvent pas être améliorées. Ces solutions pourront être re-travaillées à l'avenir - vous êtes libre de contribuer en soumettant des _pull requests_ !
+
diff --git a/fr/SUMMARY.md b/fr/SUMMARY.md
new file mode 100644
index 00000000..556e559d
--- /dev/null
+++ b/fr/SUMMARY.md
@@ -0,0 +1,27 @@
+- [Utilisation basique](basic.md)
+- [Écriture d'un code universel](universal.md)
+- [Structure du code source](structure.md)
+- [Gestion des routes et séparation du code](routing.md)
+- [Data Pre-fetching and State](data.md)
+- [Client Side Hydration](hydration.md)
+- [Introducing Bundle Renderer](bundle-renderer.md)
+- [Build Configuration](build-config.md)
+- [CSS Management](css.md)
+- [Head Management](head.md)
+- [Caching](caching.md)
+- [Streaming](streaming.md)
+- [API Reference](api.md)
+  - [createRenderer](api.md#createrendereroptions)
+  - [createBundleRenderer](api.md#createbundlerendererbundle-options)
+  - [Class: Renderer](api.md#class-renderer)
+  - [Class: BundleRenderer](api.md#class-bundlerenderer)
+  - [Renderer Options](api.md#renderer-options)
+    - [template](api.md#template)
+    - [clientManifest](api.md#clientmanifest)
+    - [inject](api.md#inject)
+    - [shouldPreload](api.md#shouldpreload)
+    - [runInNewContext](api.md#runinnewcontext)
+    - [basedir](api.md#basedir)
+    - [cache](api.md#cache)
+    - [directives](api.md#directives)
+  - [Webpack Plugins](api.md#webpack-plugins)
diff --git a/fr/api.md b/fr/api.md
new file mode 100644
index 00000000..8c82f6b5
--- /dev/null
+++ b/fr/api.md
@@ -0,0 +1,227 @@
+# API Reference
+
+## `createRenderer([options])`
+
+Create a [`Renderer`](#class-renderer) instance with (optional) [options](#renderer-options).
+
+``` js
+const { createRenderer } = require('vue-server-renderer')
+const renderer = createRenderer({ ... })
+```
+
+## `createBundleRenderer(bundle[, options])`
+
+Create a [`BundleRenderer`](#class-bundlerenderer) instance with a server bundle and (optional) [options](#renderer-options).
+
+``` js
+const { createBundleRenderer } = require('vue-server-renderer')
+const renderer = createBundleRenderer(serverBundle, { ... })
+```
+
+The `serverBundle` argument can be one of the following:
+
+- An absolute path to generated bundle file (`.js` or `.json`). Must start with `/` to be treated as a file path.
+
+- A bundle object generated by webpack + `vue-server-renderer/server-plugin`.
+
+- A string of JavaScript code (not recommended).
+
+See [Introducing the Server Bundle](./bundle-renderer.md) and [Build Configuration](./build-config.md) for more details.
+
+## `Class: Renderer`
+
+- #### `renderer.renderToString(vm[, context], callback)`
+
+  Render a Vue instance to string. The context object is optional. The callback is a typical Node.js style callback where the first argument is the error and the second argument is the rendered string.
+
+- #### `renderer.renderToStream(vm[, context])`
+
+  Render a Vue instance to a Node.js stream. The context object is optional. See [Streaming](./streaming.md) for more details.
+
+## `Class: BundleRenderer`
+
+- #### `bundleRenderer.renderToString([context, ]callback)`
+
+  Render the bundle to a string. The context object is optional. The callback is a typical Node.js style callback where the first argument is the error and the second argument is the rendered string.
+
+- #### `bundleRenderer.renderToStream([context])`
+
+  Render the bundle to a Node.js stream. The context object is optional. See [Streaming](./streaming.md) for more details.
+
+## Renderer Options
+
+- #### `template`
+
+  Provide a template for the entire page's HTML. The template should contain a comment `<!--vue-ssr-outlet-->` which serves as the placeholder for rendered app content.
+
+  The template also supports basic interpolation using the render context:
+
+  - Use double-mustache for HTML-escaped interpolation;
+  - Use triple-mustache for non-HTML-escaped interpolation.
+
+  The template automatically injects appropriate content when certain data is found on the render context:
+
+  - `context.head`: (string) any head markup that should be injected into the head of the page.
+
+  - `context.styles`: (string) any inline CSS that should be injected into the head of the page. Note this property will be automatically populated if using `vue-loader` + `vue-style-loader` for component CSS.
+
+  - `context.state`: (Object) initial Vuex store state that should be inlined in the page as `window.__INITIAL_STATE__`. The inlined JSON is automatically sanitized with [serialize-javascript](https://github.com/yahoo/serialize-javascript) to prevent XSS.
+
+  In addition, when `clientManifest` is also provided, the template automatically injects the following:
+
+  - Client-side JavaScript and CSS assets needed by the render (with async chunks automatically inferred);
+  - Optimal `<link rel="preload/prefetch">` resource hints for the rendered page.
+
+  You can disable all automatic injections by also passing `inject: false` to the renderer.
+
+  See also:
+
+  - [Using a Page Template](./basic.md#using-a-page-template)
+  - [Manual Asset Injection](./build-config.md#manual-asset-injection)
+
+- #### `clientManifest`
+
+  - 2.3.0+
+  - only used in `createBundleRenderer`
+
+  Provide a client build manifest object generated by `vue-server-renderer/server-plugin`. The client manifest provides the bundle renderer with the proper information for automatic asset injection into the HTML template. For more details, see [Generating clientManifest](./build-config.md#generating-clientmanifest).
+
+- #### `inject`
+
+  - 2.3.0+
+
+  Controls whether to perform automatic injections when using `template`. Defaults to `true`.
+
+  See also: [Manual Asset Injection](./build-config.md#manual-asset-injection).
+
+- #### `shouldPreload`
+
+  - 2.3.0+
+
+  A function to control what files should have `<link rel="preload">` resource hints generated.
+
+  By default, only JavaScript and CSS files will be preloaded, as they are absolutely needed for your application to boot.
+
+  For other types of assets such as images or fonts, preloading too much may waste bandwidth and even hurt performance, so what to preload will be scenario-dependent. You can control precisely what to preload using the `shouldPreload` option:
+
+  ``` js
+  const renderer = createBundleRenderer(bundle, {
+    template,
+    clientManifest,
+    shouldPreload: (file, type) => {
+      // type is inferred based on the file extension.
+      // https://fetch.spec.whatwg.org/#concept-request-destination
+      if (type === 'script' || type === 'style') {
+        return true
+      }
+      if (type === 'font') {
+        // only preload woff2 fonts
+        return /\.woff2$/.test(file)
+      }
+      if (type === 'image') {
+        // only preload important images
+        return file === 'hero.jpg'
+      }
+    }
+  })
+  ```
+
+- #### `runInNewContext`
+
+  - 2.3.0+
+  - only used in `createBundleRenderer`
+
+  By default, for each render the bundle renderer will create a fresh V8 context and re-execute the entire bundle. This has some benefits - for example, we don't need to worry about the "stateful singleton" problem we mentioned earlier. However, this mode comes at some considerable performance cost because re-executing the bundle is expensive especially when the app gets bigger.
+
+  This option defaults to `true` for backwards compatibility, but it is recommended to use `runInNewContext: false` whenever you can.
+
+  See also: [Source Code Structure](./structure.md)
+
+- #### `basedir`
+
+  - 2.2.0+
+  - only used in `createBundleRenderer`
+
+  Explicitly declare the base directory for the server bundle to resolve `node_modules` dependencies from. This is only needed if your generated bundle file is placed in a different location from where the externalized NPM dependencies are installed, or your `vue-server-renderer` is npm-linked into your current project.
+
+- #### `cache`
+
+  Provide a [component cache](./caching.md#component-level-caching) implementation. The cache object must implement the following interface (using Flow notations):
+
+  ``` js
+  type RenderCache = {
+    get: (key: string, cb?: Function) => string | void;
+    set: (key: string, val: string) => void;
+    has?: (key: string, cb?: Function) => boolean | void;
+  };
+  ```
+
+  A typical usage is passing in an [lru-cache](https://github.com/isaacs/node-lru-cache):
+
+  ``` js
+  const LRU = require('lru-cache')
+
+  const renderer = createRenderer({
+    cache: LRU({
+      max: 10000
+    })
+  })
+  ```
+
+  Note that the cache object should at least implement `get` and `set`. In addition, `get` and `has` can be optionally async if they accept a second argument as callback. This allows the cache to make use of async APIs, e.g. a redis client:
+
+  ``` js
+  const renderer = createRenderer({
+    cache: {
+      get: (key, cb) => {
+        redisClient.get(key, (err, res) => {
+          // handle error if any
+          cb(res)
+        })
+      },
+      set: (key, val) => {
+        redisClient.set(key, val)
+      }
+    }
+  })
+  ```
+
+- #### `directives`
+
+  Allows you to provide server-side implementations for your custom directives:
+
+  ``` js
+  const renderer = createRenderer({
+    directives: {
+      example (vnode, directiveMeta) {
+        // transform vnode based on directive binding metadata
+      }
+    }
+  })
+  ```
+
+  As an example, check out [`v-show`'s server-side implementation](https://github.com/vuejs/vue/blob/dev/src/platforms/web/server/directives/show.js).
+
+## Webpack Plugins
+
+The webpack plugins are provided as standalone files and should be required directly:
+
+``` js
+const VueSSRServerPlugin = require('vue-server-renderer/server-plugin')
+const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')
+```
+
+The default files generated are:
+
+- `vue-ssr-server-bundle.json` for the server plugin;
+- `vue-ssr-client-manifest.json` for the client plugin.
+
+The filenames can be customized when creating the plugin instances:
+
+``` js
+const plugin = new VueSSRServerPlugin({
+  filename: 'my-server-bundle.json'
+})
+```
+
+See [Build Configuration](./build-config.md) for more information.
diff --git a/fr/basic.md b/fr/basic.md
new file mode 100644
index 00000000..2b2b6167
--- /dev/null
+++ b/fr/basic.md
@@ -0,0 +1,150 @@
+# Utilisation basique
+
+## Installation
+
+``` bash
+npm install vue vue-server-renderer --save
+```
+
+Nous utiliserons NPM durant ce guide, mais vous pouvez utiliser [Yarn](https://yarnpkg.com/en/) à la place.
+
+#### Notes
+
+- Il est recommandé d'utiliser la version 6+ de Node.js.
+- Les versions de `vue-server-renderer` et `vue` doivent correspondre.
+- `vue-server-renderer` utilise certains modules natifs de Node.js, et par conséquent ne peut être utilisé qu'avec Node.js. Il se peut que nous fournissons une *build* plus simple qui pourra être utilisé dans d'autres environnements d'exécution JavaScript, dans le futur. 
+
+## Rendu d'une instance de Vue
+
+``` js
+// Étape 1 : Créer une instance de Vue
+const Vue = require('vue')
+const app = new Vue({
+  template: `<div>Bonjour le monde</div>`
+})
+
+// Étape 2 : Créer un moteur de rendu
+const renderer = require('vue-server-renderer').createRenderer()
+
+// Étape 3 : Faire le rendu de l'instance de Vue en HTML
+renderer.renderToString(app, (err, html) => {
+  if (err) throw err
+  console.log(html)
+  // => <p data-server-rendered="true">Bonjour le monde</p>
+})
+```
+
+## Integration avec un serveur
+
+L'utilisation avec un serveur Node.js, par exemple [Express](https://expressjs.com/), est plutôt simple :
+
+``` bash
+npm install express --save
+```
+---
+``` js
+const Vue = require('vue')
+const server = require('express')()
+const renderer = require('vue-server-renderer').createRenderer()
+
+server.get('*', (req, res) => {
+  const app = new Vue({
+    data: {
+      url: req.url
+    },
+    template: `<div>L'URL visitée est : {{ url }}</div>`
+  })
+
+  renderer.renderToString(app, (err, html) => {
+    if (err) {
+      res.status(500).end('Internal Server Error')
+      return
+    }
+    res.end(`
+      <!DOCTYPE html>
+      <html lang="en">
+        <head><title>Bonjour</title></head>
+        <body>${html}</body>
+      </html>
+    `)
+  })
+})
+
+server.listen(8080)
+```
+
+## Utilisation d'un modèle de page
+
+Pendant le rendu de l'application Vue, le moteur de rendu ne génère que le code HTML de l'application.
+Dans l'exemple précédent, il a fallu entourer le résultat par du code HTML supplémentaire.
+
+Pour simplifier cela, il est possible de fournir un modèle de page pendant la création moteur de rendu.
+La plupart du temps, ce modèle de page sera dans situé dans son propre fichier, ex : `index.template.html` :
+
+``` html
+<!DOCTYPE html>
+<html lang="fr">
+  <head><title>Bonjour</title></head>
+  <body>
+    <!--vue-ssr-outlet-->
+  </body>
+</html>
+```
+
+Observez le commentaire `<!--vue-ssr-outlet-->` -- c'est là que le code HTML de l'application sera injecté.
+
+On peut maintenant lire et passer le fichier dans le moteur de rendu de Vue :
+
+``` js
+const renderer = createRenderer({
+  template: require('fs').readFileSync('./index.template.html', 'utf-8')
+})
+
+renderer.renderToString(app, (err, html) => {
+  console.log(html) // sera la page entière avec le contenu de application injecté.
+})
+```
+
+### Interpolation de modèle de page
+
+Le modèle de page supporte également des interpolations simple. Avec le modèle de page suivant :
+
+``` html
+<html>
+  <head>
+    <title>{{ title }}</title>
+    {{{ meta }}}
+  </head>
+  <body>
+    <!--vue-ssr-outlet-->
+  </body>
+</html>
+```
+
+On peut utiliser l'interpolation de données en passant un "objet contexte pour le rendu" comme deuxième argument de  `renderToString` :
+
+``` js
+const context = {
+  title: 'bonjour',
+  meta: `
+    <meta ...>
+    <meta ...>
+  `
+}
+
+renderer.renderToString(app, context, (err, html) => {
+  // le titre de la page sera "bonjour"
+  // avec les tags meta injectés
+})
+```
+
+L'objet `context` peut aussi être partagé avec l'instance de l'application Vue, permettant les composants de modifier ces données de manière dynamique, pour l'interpolation de modèle de page. 
+
+De plus, le modèle de page supporte quelques fonctionnalités avancées telles que :
+
+- Injection automatique de CSS *critique* lors de l'utilisation `*.vue` components ;
+- Injection automatique des ressources et suggestions lors de l'utilisation de `clientManifest` ;
+- Injection automatique et protection XSS durant l'incorporation de données Vuex, pour l'hydratation côté client.
+
+
+Nous en discuterons lorsque nous présenterons les concepts associés plus tard dans le guide.
diff --git a/fr/build-config.md b/fr/build-config.md
new file mode 100644
index 00000000..3beb9032
--- /dev/null
+++ b/fr/build-config.md
@@ -0,0 +1,209 @@
+# Build Configuration
+
+We will assume you already know how to configure webpack for a client-only project. The config for an SSR project will be largely similar, but we suggest breaking the config into three files: *base*, *client* and *server*. The base config contains config shared for both environments, such as output path, aliases, and loaders. The server config and client config can simply extend the base config using [webpack-merge](https://github.com/survivejs/webpack-merge).
+
+## Server Config
+
+The server config is meant for generating the server bundle that will be passed to `createBundleRenderer`. It should look like this:
+
+``` js
+const merge = require('webpack-merge')
+const nodeExternals = require('wepback-node-externals')
+const baseConfig = require('./webpack.base.config.js')
+const VueSSRServerPlugin = require('vue-server-renderer/server-plugin')
+
+module.exports = merge(baseConfig, {
+  // Point entry to your app's server entry file
+  entry: '/path/to/entry-server.js',
+
+  // This allows webpack to handle dynamic imports in a Node-appropriate
+  // fashion, and also tells `vue-loader` to emit server-oriented code when
+  // compiling Vue components.
+  target: 'node',
+
+  // For bundle renderer source map support
+  devtool: 'source-map',
+
+  // This tells the server bundle to use Node-style exports
+  output: {
+    libraryTarget: 'commonjs2'
+  },
+
+  // https://webpack.js.org/configuration/externals/#function
+  // https://github.com/liady/webpack-node-externals
+  // Externalize app dependencies. This makes the server build much faster
+  // and generates a smaller bundle file.
+  externals: nodeExternals({
+    // do not externalize dependencies that need to be processed by webpack.
+    // you can add more file types here e.g. raw *.vue files
+    whitelist: /\.css$/
+  }),
+
+  // This is the plugin that turns the entire output of the server build
+  // into a single JSON file. The default file name will be
+  // `vue-ssr-server-bundle.json`
+  plugins: [
+    new VueSSRServerPlugin()
+  ]
+})
+```
+
+After `vue-ssr-server-bundle.json` has been generated, simply pass the file path to `createBundleRenderer`:
+
+``` js
+const { createBundleRenderer } = require('vue-server-renderer')
+const renderer = createBundleRenderer('/path/to/vue-ssr-server-bundle.json', {
+  // ...other renderer options
+})
+```
+
+Alternatively, you can also pass the bundle as an Object to `createBundleRenderer`. This is useful for hot-reload during development - see the HackerNews demo for a [reference setup](https://github.com/vuejs/vue-hackernews-2.0/blob/master/build/setup-dev-server.js).
+
+## Client Config
+
+The client config can remain largely the same with the base config. Obviously you need to point `entry` to your client entry file. Aside from that, if you are using `CommonsChunkPlugin`, make sure to use it only in the client config because the server bundle requires a single entry chunk.
+
+### Generating `clientManifest`
+
+> requires version 2.3.0+
+
+In addition to the server bundle, we can also generate a client build manifest. With the client manifest and the server bundle, the renderer now has information of both the server *and* client builds, so it can automatically infer and inject [preload / prefetch directives](https://css-tricks.com/prefetching-preloading-prebrowsing/) and css links / script tags into the rendered HTML.
+
+The benefits is two-fold:
+
+1. It can replace `html-webpack-plugin` for injecting the correct asset URLs when there are hashes in your generated filenames.
+
+2. When rendering a bundle that leverages webpack's on-demand code splitting features, we can ensure the optimal chunks are preloaded / prefetched, and also intelligently inject `<script>` tags for needed async chunks to avoid waterfall requests on the client, thus improving TTI (time-to-interactive).
+
+To make use of the client manifest, the client config would look something like this:
+
+``` js
+const webpack = require('webpack')
+const merge = require('webpack-merge')
+const baseConfig = require('./webpack.base.config.js')
+const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')
+
+module.exports = merge(baseConfig, {
+  entry: '/path/to/entry-client.js',
+  plugins: [
+    // Important: this splits the webpack runtime into a leading chunk
+    // so that async chunks can be injected right after it.
+    // this also enables better caching for your app/vendor code.
+    new webpack.optimize.CommonsChunkPlugin({
+      name: "manifest",
+      minChunks: Infinity
+    }),
+    // This plugins generates `vue-ssr-client-manifest.json` in the
+    // output directory.
+    new VueSSRClientPlugin()
+  ]
+})
+```
+
+You can then use the generated client manifest, together with a page template:
+
+``` js
+const { createBundleRenderer } = require('vue-server-renderer')
+
+const template = require('fs').readFileSync('/path/to/template.html', 'utf-8')
+const serverBundle = require('/path/to/vue-ssr-server-bundle.json')
+const clientManifest = require('/path/to/vue-ssr-client-manifest.json')
+
+const renderer = createBundleRenderer(serverBundle, {
+  template,
+  clientManifest
+})
+```
+
+With this setup, your server-rendered HTML for a build with code-splitting will look something like this (everything auto-injected):
+
+``` html
+<html>
+  <head>
+    <!-- chunks used for this render will be preloaded -->
+    <link rel="preload" href="/manifest.js" as="script">
+    <link rel="preload" href="/main.js" as="script">
+    <link rel="preload" href="/0.js" as="script">
+    <!-- unused async chunks will be prefetched (lower priority) -->
+    <link rel="prefetch" href="/1.js" as="script">
+  </head>
+  <body>
+    <!-- app content -->
+    <div data-server-rendered="true"><div>async</div></div>
+    <!-- manifest chunk should be first -->
+    <script src="/manifest.js"></script>
+    <!-- async chunks injected before main chunk -->
+    <script src="/0.js"></script>
+    <script src="/main.js"></script>
+  </body>
+</html>`
+```
+
+### Manual Asset Injection
+
+By default, asset injection is automatic when you provide the `template` render option. But sometimes you might want finer-grained control over how assets are injected into the template, or maybe you are not using a template at all. In such a case, you can pass `inject: false` when creating the renderer and manually perform asset injection.
+
+In the `renderToString` callback, the `context` object you passed in will expose the following methods:
+
+- `context.renderStyles()`
+
+  This will return inline `<style>` tags containing all the critical CSS collected from the `*.vue` components used during the render. See [CSS Management](./css.md) for more details.
+
+  If a `clientManifest` is provided, the returned string will also contain `<link rel="stylesheet">` tags for webpack-emitted CSS files (e.g. CSS extracted with `extract-text-webpack-plugin` or imported with `file-loader`)
+
+- `context.renderState(options?: Object)`
+
+  This method serializes `context.state` and returns an inline script that embeds the state as `window.__INITIAL_STATE__`.
+
+  The context state key and window state key can both be customized by passing an options object:
+
+  ``` js
+  context.renderState({
+    contextKey: 'myCustomState',
+    windowKey: '__MY_STATE__'
+  })
+
+  // -> <script>window.__MY_STATE__={...}</script>
+  ```
+
+- `context.renderScripts()`
+
+  - requires `clientManifest`
+
+  This method returns the `<script>` tags needed for the client application to boot. When using async code-splitting in the app code, this method will intelligently infer the correct async chunks to include.
+
+- `context.renderResourceHints()`
+
+  - requires `clientManifest`
+
+  This method returns the `<link rel="preload/prefetch">` resource hints needed for the current rendered page. By default it will:
+
+  - Preload the JavaScript and CSS files needed by the page
+  - Prefetch async JavaScript chunks that might be needed later
+
+  Preloaded files can be further customized with the [`shouldPreload`](./api.md#shouldpreload) option.
+
+- `context.getPreloadFiles()`
+
+  - requires `clientManifest`
+
+  This method does not return a string - instead, it returns an Array of file objects representing the assets that should be preloaded. This can be used to programmatically perform HTTP/2 server push.
+
+Since the `template` passed to `createBundleRenderer` will be interpolated using `context`, you can make use of these methods inside the template (with `inject: false`):
+
+``` html
+<html>
+  <head>
+    <!-- use triple mustache for non-HTML-escaped interpolation -->
+    {{{ renderResourceHints() }}}
+    {{{ renderStyles() }}}
+  </head>
+  <body>
+    <!--vue-ssr-outlet-->
+    {{{ renderState() }}}
+    {{{ renderScripts() }}}
+  </body>
+</html>
+```
+
+If you are not using `template` at all, you can concatenate the strings yourself.
diff --git a/fr/bundle-renderer.md b/fr/bundle-renderer.md
new file mode 100644
index 00000000..2be30fe9
--- /dev/null
+++ b/fr/bundle-renderer.md
@@ -0,0 +1,58 @@
+# Introducing Bundle Renderer
+
+## Problems with Basic SSR
+
+Up to this point, we have assumed that the bundled server-side code will be directly used by the server via `require`:
+
+``` js
+const createApp = require('/path/to/built-server-bundle.js')
+```
+
+This is straightforward, however whenever you edit your app source code, you would have to stop and restart the server. This hurts productivity quite a bit during development. In addition, Node.js doesn't support source maps natively.
+
+## Enter BundleRenderer
+
+`vue-server-renderer` provides an API called `createBundleRenderer` to deal with this problem. With a custom webpack plugin, the server bundle is generated as a special JSON file that can be passed to the bundle renderer. Once the bundle renderer is created, usage is the same as the normal renderer, however the bundle renderer provides the following benefits:
+
+- Built-in source map support (with `devtool: 'source-map'` in webpack config)
+
+- Hot-reload during development and even deployment (by simply reading the updated bundle and re-creating the renderer instance)
+
+- Critical CSS injection (when using `*.vue` files): automatically inlines the CSS needed by components used during the render. See the [CSS](./css.md) section for more details.
+
+- Asset injection with [clientManifest](./client-manifest.md): automatically infers the optimal preload and prefetch directives, and the code-split chunks needed for the initial render.
+
+---
+
+We will discuss how to configure webpack to generate the build artifacts needed by the bundle renderer in the next section, but for now let's assume we already have what we need, and this is how to create a use a bundle renderer:
+
+``` js
+const { createBundleRenderer } = require('vue-server-renderer')
+
+const renderer = createBundleRenderer(serverBundle, {
+  runInNewContext: false, // recommended
+  template, // (optinal) page template
+  clientManifest // (optional) client build manifest
+})
+
+// inside a server handler...
+server.get('*', (req, res) => {
+  const context = { url: req.url }
+  // No need to pass an app here because it is auto-created by the
+  // executing the bundle. Now our server is decoupled from our Vue app!
+  renderer.renderToString(context, (err, html) => {
+    // handle error...
+    res.end(html)
+  })
+})
+```
+
+When `rendertoString` is called on a bundle renderer, it will automatically execute the function exported by the bundle to create an app instance (passing `context` as the argument) , and then render it.
+
+---
+
+### The `runInNewContext` Option
+
+By default, for each render the bundle renderer will create a fresh V8 context and re-execute the entire bundle. This has some benefits - for example, we don't need to worry about the "stateful singleton" problem we mentioned earlier. However, this mode comes at some considerable performance cost because re-executing the bundle is expensive especially when the app gets bigger.
+
+In `vue-server-renderer >= 2.3.0`, this option still defaults to `true` for backwards compatibility, but it is recommended to use `runInNewContext: false` whenever you can.
diff --git a/fr/caching.md b/fr/caching.md
new file mode 100644
index 00000000..5568a032
--- /dev/null
+++ b/fr/caching.md
@@ -0,0 +1,87 @@
+# Caching
+
+Although Vue's SSR is quite fast, it can't match the performance of pure string-based templating due to the cost of creating component instances and Virtual DOM nodes. In cases where SSR performance is critical, wisely leveraging caching strategies can greatly improve response time and reduce server load.
+
+## Page-level Caching
+
+A server-rendered app in most cases relies on external data, so the content is dynamic by nature and cannot be cached for extended periods. However, if the content is not user-specific (i.e. for the same URL it always renders the same content for all users), we can leverage a strategy called [micro-caching](https://www.nginx.com/blog/benefits-of-microcaching-nginx/) to drastically improve our app's capability of handling high traffic.
+
+This is usually done at the Nginx layer, but we can also implement it in Node.js:
+
+``` js
+const microCache = LRU({
+  max: 100,
+  maxAge: 1000 // Important: entries expires after 1 second.
+})
+
+const isCacheable = req => {
+  // implement logic to check if the request is user-specific.
+  // only non-user-specific pages are cache-able
+}
+
+server.get('*', (req, res) => {
+  const cacheable = isCacheable(req)
+  if (cacheable) {
+    const hit = microCache.get(req.url)
+    if (hit) {
+      return res.end(hit)
+    }
+  }
+
+  renderer.renderToString((err, html) => {
+    res.end(html)
+    if (cacheable) {
+      microCache.set(req.url, html)
+    }
+  })
+})
+```
+
+Since the content is cached for only one second, users will not see outdated content. However, this means the server only has to perform at most one full render per second for each cached page.
+
+## Component-level Caching
+
+`vue-server-renderer` has built-in support for component-level caching. To enable it you need to provide a [cache implementation](./api.md#cache) when creating the renderer. Typical usage is passing in an [lru-cache](https://github.com/isaacs/node-lru-cache):
+
+``` js
+const LRU = require('lru-cache')
+
+const renderer = createRenderer({
+  cache: LRU({
+    max: 10000,
+    maxAge: ...
+  })
+})
+```
+
+You can then cache a component by implementing a `serverCacheKey` function:
+
+``` js
+export default {
+  name: 'item', // required
+  props: ['item'],
+  serverCacheKey: props => props.item.id,
+  render (h) {
+    return h('div', this.item.id)
+  }
+}
+```
+
+Note that cache-able component **must also define a unique "name" option**. With a unique name, the cache key is thus per-component: you don't need to worry about two components returning the same key.
+
+The key returned from `serverCacheKey` should contain sufficient information to represent the shape of the render result. The above is a good implementation if the render result is solely determined by `props.item.id`. However, if the item with the same id may change over time, or if render result also relies on another prop, then you need to modify your `getCacheKey` implementation to take those other variables into account.
+
+Returning a constant will cause the component to always be cached, which is good for purely static components.
+
+### When to use component caching
+
+If the renderer hits a cache for a component during render, it will directly reuse the cached result for the entire sub tree. This means you should **NOT** cache a component when:
+
+- It has child components that may rely on global state.
+- It has child components that produces side effects on the render `context`.
+
+Component caching should therefore be applied carefully to address performance bottlenecks. In most cases, you shouldn't and don't need to cache single-instance components. The most common type of components that are suitable for caching are ones repeated in big `v-for` lists. Since these components are usually driven by objects in database collections, they can make use of a simple caching strategy: generate their cache keys using their unique id plus the last updated timestamp:
+
+``` js
+serverCacheKey: props => props.item.id + '::' + props.item.last_updated
+```
diff --git a/fr/css.md b/fr/css.md
new file mode 100644
index 00000000..7d6e846d
--- /dev/null
+++ b/fr/css.md
@@ -0,0 +1,114 @@
+# CSS Management
+
+The recommended way to manage CSS is to simply use `<style>` inside `*.vue` single file components, which offers:
+
+- Collocated, component-scoped CSS
+- Ability to leverage pre-processors or PostCSS
+- Hot-reload during development
+
+More importantly, `vue-style-loader`, the loader used internally by `vue-loader`, has some special features for server rendering:
+
+- Universal authoring experience for client and server.
+
+- Automatic critical CSS when using `bundleRenderer`.
+
+  If used during a server render, a component's CSS can be collected and inlined in the HTML (automatically handled when using `template` option). On the client, when the component is used for the first time, `vue-style-loader` will check if there is already server-inlined CSS for this component - if not, the CSS will be dynamically injected via a `<style>` tag.
+
+- Common CSS Extraction.
+
+  This setup support using [`extract-text-webpack-plugin`](https://github.com/webpack-contrib/extract-text-webpack-plugin) to extract the CSS in the main chunk into a separate CSS file (auto injected with `template`), which allows the file to be individually cached. This is recommended when there is a lot of shared CSS.
+
+  CSS inside async components will remain inlined as JavaScript strings and handled by `vue-style-loader`.
+
+## Enabling CSS Extraction
+
+To extract CSS from `*.vue` files, use `vue-loader`'s `extractCSS` option (requires `vue-loader>=12.0.0`):
+
+``` js
+// webpack.config.js
+const ExtractTextPlugin = require('extract-text-webpack-plugin')
+
+// CSS extraction should only be enabled for production
+// so that we still get hot-reload during development.
+const isProduction = process.env.NODE_ENV === 'production'
+
+module.exports = {
+  // ...
+  module: {
+    rules: [
+      {
+        test: /\.vue$/,
+        loader: 'vue-loader',
+        options: {
+          // enable CSS extraction
+          extractCSS: isProduction
+        }
+      },
+      // ...
+    ]
+  },
+  plugins: isProduction
+    // make sure to add the plugin!
+    ? [new ExtractTextPlugin({ filename: 'common.[chunkhash].css' })]
+    : []
+}
+```
+
+Note that the above config only applies to styles in `*.vue` files, but you can use `<style src="./foo.css">` to import external CSS into Vue components.
+
+If you wish to import CSS from JavaScript, e.g. `import 'foo.css'`, you need to configure the appropriate loaders:
+
+``` js
+module.exports = {
+  // ...
+  module: {
+    rules: [
+      {
+        test: /\.css$/,
+        // important: use vue-style-loader instead of style-loader
+        use: isProduction
+          ? ExtractTextPlugin.extract({
+              use: 'css-loader',
+              fallback: 'vue-style-loader'
+            })
+          : ['vue-style-loader', 'css-loader']
+      }
+    ]
+  },
+  // ...
+}
+```
+
+## Importing Styles from Dependencies
+
+A few things to take note when importing CSS from an NPM dependency:
+
+1. It should not be externalized in the server build.
+
+2. If using CSS extraction + vendor extracting with `CommonsChunkPlugin`, `extract-text-webpack-plugin` will run into problems if the extracted CSS in inside an extracted vendors chunk. To work around this, avoid including CSS files in the vendor chunk. An example client webpack config:
+
+  ``` js
+  module.exports = {
+    // ...
+    plugins: [
+      // it is common to extract deps into a vendor chunk for better caching.
+      new webpack.optimize.CommonsChunkPlugin({
+        name: 'vendor',
+        minChunks: function (module) {
+          // a module is extracted into the vendor chunk when...
+          return (
+            // if it's inside node_modules
+            /node_modules/.test(module.context) &&
+            // do not externalize if the request is a CSS file
+            !/\.css$/.test(module.request)
+          )
+        }
+      }),
+      // extract webpack runtime & manifest
+      new webpack.optimize.CommonsChunkPlugin({
+        name: 'manifest'
+      }),
+      // ...
+    ]
+  }
+  ```
diff --git a/fr/data.md b/fr/data.md
new file mode 100644
index 00000000..7d41bd38
--- /dev/null
+++ b/fr/data.md
@@ -0,0 +1,259 @@
+# Data Pre-Fetching and State
+
+## Data Store
+
+During SSR, we are essentially rendering a "snapshot" of our app, so if the app relies on some asynchronous data, **these data need to be pre-fetched and resolved before we start the rendering process**.
+
+Another concern is that on the client, the same data needs to be available before we mount the client side app - otherwise the client app would render using different state and the hydration would fail.
+
+To address this, the fetched data needs to live outside the view components, in a dedicated data store, or a "state container". On the server, we can pre-fetch and fill data into the store before rendering. In addition, we will serialize and inline the state in the HTML. The client-side store can directly pick up the inlined state before we mount the app.
+
+We will be using the official state management library [Vuex](https://github.com/vuejs/vuex/) for this purpose. Let's create a `store.js` file, with some mocked logic for fetching an item based on an id:
+
+``` js
+// store.js
+import Vue from 'vue'
+import Vuex from 'vuex'
+
+Vue.use(Vuex)
+
+// Assume we have a universal API that returns Promises
+// and ignore the implementation details
+import { fetchItem } from './api'
+
+export function createStore () {
+  return new Vuex.Store({
+    state: {
+      items: {}
+    },
+    actions: {
+      fetchItem ({ commit }, id) {
+        // return the Promise via store.dispatch() so that we know
+        // when the data has been fetched
+        return fetchItem(id).then(item => {
+          commit('setItem', { id, item })
+        })
+      }
+    },
+    mutations: {
+      setItem (state, { id, item }) {
+        Vue.set(state.items, id, item)
+      }
+    }
+  })
+}
+```
+
+And update `app.js`:
+
+``` js
+// app.js
+import Vue from 'vue'
+import App from './App.vue'
+import { createRouter } from './router'
+import { createStore } from './store'
+import { sync } from 'vuex-router-sync'
+
+export function createApp () {
+  // create router and store instances
+  const router = createRouter()
+  const store = createStore()
+
+  // sync so that route state is available as part of the store
+  sync(store, router)
+
+  // create the app instance, injecting both the router and the store
+  const app = new Vue({
+    router,
+    store,
+    render: h => h(App)
+  })
+
+  // expose the app, the router and the store.
+  return { app, router, store }
+}
+```
+
+## Logic Collocation with Components
+
+So, where do we place the code that dispatches the data-fetching actions?
+
+The data we need to fetch is determined by the route visited - which also determines what components are rendered. In fact, the data needed for a given route is also the data needed by the components rendered at that route. So it would be natural to place the data fetching logic inside route components.
+
+We will expose a custom static function `asyncData` on our route components. Note because this function will be called before the components are instantiated, it doesn't have access to `this`. The store and route information needs to be passed in as arguments:
+
+``` html
+<!-- Item.vue -->
+<template>
+  <div>{{ item.title }}</div>
+</template>
+
+<script>
+export default {
+  asyncData ({ store, route }) {
+    // return the Promise from the action
+    return store.dispatch('fetchItem', route.params.id)
+  },
+
+  computed: {
+    // display the item from store state.
+    items () {
+      return this.$store.state.items[this.$route.params.id]
+    }
+  }
+}
+</script>
+```
+
+## Server Data Fetching
+
+In `entry-server.js` we can get the components matched by a route with `router.getMatchedComponents()`, and call `asyncData` if the component exposes it. Then we need to attach resolved state to the render context.
+
+``` js
+// entry-server.js
+import { createApp } from './app'
+
+export default context => {
+  return new Promise((resolve, reject) => {
+    const { app, router, store } = createApp()
+
+    router.push(context.url)
+
+    router.onReady(() => {
+      const matchedComponents = router.getMatchedComponents()
+      if (!matchedComponents.length) {
+        reject({ code: 404 })
+      }
+
+      // call asyncData() on all matched route components
+      Promise.all(matchedComponents.map(Component => {
+        if (Component.asyncData) {
+          return Component.asyncData({
+            store,
+            route: router.currentRoute
+          })
+        }
+      })).then(() => {
+        // After all preFetch hooks are resolved, our store is now
+        // filled with the state needed to render the app.
+        // When we attach the state to the context, and the `template` option
+        // is used for the renderer, the state will automatically be
+        // serialized and injected into the HTML as window.__INITIAL_STATE__.
+        context.state = store.state
+
+        resolve(app)
+      }).catch(reject)
+    }, reject)
+  })
+}
+```
+
+When using `template`, `context.state` will automatically be embedded in the final HTML as `window.__INITIAL__` state. On the client, the store should pick up the state before mounting the application:
+
+``` js
+// entry-client.js
+
+const { app, router, store } = createApp()
+
+if (window.__INITIAL_STATE__) {
+  store.replaceState(window.__INITIAL_STATE__)
+}
+```
+
+## Client Data Fetching
+
+On the client, there are two different approaches for handling data fetching:
+
+1. **Resolve data before route navigation:**
+
+  With this strategy, the app will stay on the current view until the data needed by the incoming view has been resolved. The benefit is that the incoming view can directly render the full content when it's ready, but if the data fetching takes a long time, the user will feel "stuck" on the current view. It is therefore recommended to provide a data loading indicator if using this strategy.
+
+  We can implement this strategy on the client by checking matched components and invoking their `asyncData` function inside a global route hook. Note we should register this hook after the initial route is ready so that we don't unnecessarily fetch the server-fetched data again.
+
+  ``` js
+  // entry-client.js
+
+  // ...omitting unrelated code
+
+  router.onReady(() => {
+    // Add router hook for handling asyncData.
+    // Doing it after initial route is resolved so that we don't double-fetch
+    // the data that we already have. Using router.beforeResolve() so that all
+    // async components are resolved.
+    router.beforeResolve((to, from, next) => {
+      const matched = router.getMatchedComponents(to)
+      const prevMatched = router.getMatchedComponents(from)
+
+      // we only care about none-previously-rendered components,
+      // so we compare them until the two matched lists differ
+      let diffed = false
+      const activated = matched.filter((c, i) => {
+        return diffed || (diffed = (prevMatched[i] !== c))
+      })
+
+      if (!activated.length) {
+        return next()
+      }
+
+      // this is where we should trigger a loading indicator if there is one
+
+      Promise.all(activated.map(c => {
+        if (c.asyncData) {
+          return c.asyncData({ store, route: to })
+        }
+      })).then(() => {
+
+        // stop loading indicator
+
+        next()
+      }).catch(next)
+    })
+
+    app.$mount('#app')
+  })
+  ```
+
+2. **Fetch data after the matched view is rendered:**
+
+  This strategy places the client-side data-fetching logic in a view component's `beforeMount` function. This allows the views to switch instantly when a route navigation is triggered, so the app feels a bit more responsive. However, the incoming view will not have the full data available when it's rendered. It is therefore necessary to have a conditional loading state for each view component that uses this strategy.
+
+  This can be achieved with a client-only global mixin:
+
+  ``` js
+  Vue.mixin({
+    beforeMount () {
+      const { asyncData } = this.$options
+      if (asyncData) {
+        // assign the fetch operation to a promise
+        // so that in components we can do `this.dataPromise.then(...)` to
+        // perform other tasks after data is ready
+        this.dataPromise = asyncData({
+          store: this.$store,
+          route: this.$route
+        })
+      }
+    }
+  })
+  ```
+
+The two strategies are ultimately different UX decisions and should be picked based on the actual scenario of the app you are building. But regardless of which strategy you pick, the `asyncData` function should also be called when a route component is reused (same route, but params or query changed. e.g. from `user/1` to `user/2`). We can also handle this with a client-only global mixin:
+
+``` js
+Vue.mixin({
+  beforeRouteUpdate (to, from, next) {
+    const { asyncData } = this.$options
+    if (asyncData) {
+      asyncData({
+        store: this.$store,
+        route: to
+      }).then(next).catch(next)
+    } else {
+      next()
+    }
+  }
+})
+```
+
+---
+
+Phew, that was a lot of code! This is because universal data-fetching is probably the most complex problem in a server-rendered app and we are laying the groundwork for easier further development. Once the boilerplate is set up, authoring individual components will be actually quite pleasant.
diff --git a/fr/head.md b/fr/head.md
new file mode 100644
index 00000000..864f824f
--- /dev/null
+++ b/fr/head.md
@@ -0,0 +1,108 @@
+# Head Management
+
+Similar to asset injection, head management follows the same idea: we can dynamically attach data to the render `context` in a component's lifecycle, and then interpolate those data in `template`.
+
+To do that we need to have access to the SSR context inside a nested component. We can simply pass the `context` to `createApp()` and expose it on the root instance's `$options`:
+
+``` js
+// app.js
+
+export function createApp (ssrContext) {
+  // ...
+  const app = new Vue({
+    router,
+    store,
+    // all child components can access this as this.$root.$options.ssrContext
+    ssrContext,
+    render: h => h(App)
+  })
+  // ...
+}
+```
+
+This can also be done via `provide/inject`, but since we know it's going to be on `$root`, we can avoid the injection resolution costs.
+
+With the context injected, we can write a simple mixin to perform title management:
+
+``` js
+// title-mixin.js
+
+function getTitle (vm) {
+  // components can simply provide a `title` option
+  // which can be either a string or a function
+  const { title } = vm.$options
+  if (title) {
+    return typeof title === 'function'
+      ? title.call(vm)
+      : title
+  }
+}
+
+const serverTitleMixin = {
+  created () {
+    const title = getTitle(this)
+    if (title) {
+      this.$root.$options.ssrContext.title = title
+    }
+  }
+}
+
+const clientTitleMixin = {
+  mounted () {
+    const title = getTitle(this)
+    if (title) {
+      document.title = title
+    }
+  }
+}
+
+// VUE_ENV can be injected with webpack.DefinePlugin
+export default process.env.VUE_ENV === 'server'
+  ? serverTitleMixin
+  : clientTitleMixin
+```
+
+Now, a route component can make use of this to control the document title:
+
+``` js
+// Item.vue
+export default {
+  mixins: [titleMixin],
+  title () {
+    return this.item.title
+  }
+
+  asyncData ({ store, route }) {
+    return store.dispatch('fetchItem', route.params.id)
+  },
+
+  computed: {
+    item () {
+      return this.$store.state.items[this.$route.params.id]
+    }
+  }
+}
+```
+
+And inside the `template` passed to bundle renderer:
+
+``` html
+<html>
+  <head>
+    <title>{{ title }}</title>
+  </head>
+  <body>
+    ...
+  </body>
+</html>
+```
+
+**Notes:**
+
+- Use double-mustache (HTML-escaped interpolation) to avoid XSS attacks.
+
+- You should provide a default title when creating the `context` object in case no component has set a title during render.
+
+---
+
+Using the same strategy, you can easily expand this mixin into a generic head management utility.
diff --git a/fr/hydration.md b/fr/hydration.md
new file mode 100644
index 00000000..6a11574f
--- /dev/null
+++ b/fr/hydration.md
@@ -0,0 +1,32 @@
+# Client Side Hydration
+
+In `entry-client.js`, we are simply mounting the app with this line:
+
+``` js
+// this assumes App.vue template root element has id="app"
+app.$mount('#app')
+```
+
+Since the server has already rendered the markup, we obviously do not want to throw that away and re-create all the DOM elements. Instead, we want to "hydrate" the static markup and make it interactive.
+
+If you inspect the server-rendered output, you will notice that the app's root element has a special attribute:
+
+``` js
+<div id="app" data-server-rendered="true">
+```
+
+The `data-server-rendered` special attribute lets the client-side Vue know that the markup is rendered by the server and it should mount in hydration mode.
+
+In development mode, Vue will assert the client-side generated virtual DOM tree matches the DOM structure rendered from the server. If there is a mismatch, it will bail hydration, discard existing DOM and render from scratch. **In production mode, this assertion is disabled for maximum performance.**
+
+### Hydration Caveats
+
+One thing to be aware of when using SSR + client hydration is some special HTML structures that may be altered by the browser. For example, when you write this in a Vue template:
+
+``` html
+<table>
+  <tr><td>hi</td></tr>
+</table>
+```
+
+The browser will automatically inject `<tbody>` inside `<table>`, however, the virtual DOM generated by Vue does not contain `<tbody>`, so it will cause a mismatch. To ensure correct matching, make sure to write valid HTML in your templates.
diff --git a/fr/routing.md b/fr/routing.md
new file mode 100644
index 00000000..a0ecd0e7
--- /dev/null
+++ b/fr/routing.md
@@ -0,0 +1,156 @@
+# Gestion des routes et séparation du code
+
+## Gestion des routes avec `vue-router`
+
+Vous avez sans doute remarqué que notre code serveur utilise le handler `*` qui accepte n'importe quelle URL. Cela nous permet de ré-utiliser la même configuration des routes pour le client et le serveur !
+
+Il est recommandé d'utiliser le routeur officiel de Vue `vue-router`. Commençons par créer un fichier où sera créé le routeur . Similaire à `createApp`, nous aurons besoin d'une nouvelle instance du routeur pour chaque requêtes, donc ce fichier export une fonction `createRouter` :
+
+``` js
+// router.js
+import Vue from 'vue'
+import Router from 'vue-router'
+
+Vue.use(Router)
+
+export function createRouter () {
+  return new Router({
+    mode: 'history',
+    routes: [
+      // ...
+    ]
+  })
+}
+```
+
+Et modifier `app.js` : 
+
+``` js
+// app.js
+import Vue from 'vue'
+import App from './App.vue'
+import { createRouter } from './router'
+
+export function createApp () {
+  // crée l'instance du routeur 
+  const router = createRouter()
+
+  const app new Vue({
+    // injection du routeur dans l'instance de Vue
+    router,
+    render: h => h(App)
+  })
+
+  // retourne l'application et le routeur 
+  return { app, router }
+}
+```
+
+Maintenant, il faut implémenter la logique des routes dans `entry-server.js` :
+
+``` js
+// entry-server.js
+import { createApp } from './app'
+
+export default context => {
+
+  // vu qu'il peut potentiellement avoir des composants ou des connecteurs
+  // de routes asynchrones, on retourne une Promise de telle sorte que
+  // le serveur pour attendre jusqu'à ce que tout soit prêt avant le rendu
+  return new Promise((resolve, reject) => {
+    const { app, router } = createApp()
+
+    // défini la location du routeur serveur
+    router.push(context.url)
+
+    // on attend que le routeur ait terminé de traiter avec les composants et 
+    // connecteurs asynchrones
+    router.onReady(() => {
+      const matchedComponents = router.getMatchedComponents()
+      // pas de routes correspondantes, on rejette la requête avec une 404
+      if (!matchedComponents.length) {
+        reject({ code: 404 })
+      }
+
+      // la Promise doit résoudre l'instance de l'application, qui pourra 
+      // ensuite être rendue
+      resolve(app)
+    }, reject)
+  })
+}
+```
+
+En assumant que le bundle serveur soit déjà fait (encore une fois, on ignore l'étape de configuration du build pour l'instant), l'usage de ce bundle ressemblerait à ça :
+
+``` js
+// server.js
+const createApp = require('/path/to/built-server-bundle.js')
+
+server.get('*', (req, res) => {
+  const context = { url: req.url }
+
+  createApp(context).then(app => {
+    renderer.renderToString(app, (err, html) => {
+      if (err) {
+        if (err.code === 404) {
+          res.status(404).end('Page not found')
+        } else {
+          res.status(500).end('Internal Server Error')
+        }
+      } else {
+        res.end(html)
+      }
+    })
+  })
+})
+```
+
+## Séparation du code
+
+La séparation du code, ou les parties *lazy-loadées* de votre application, aide à réduire le montant de ressources qui ont besoin d'être téléchargées par le navigateur pour le rendu initial, et peut grandement améliorer le TTI (time-to-interactive) pour les grosses applications. Le but est de "charger uniquement ce qui est nécessaire" pour l'écran initial.
+
+Vue permet de créer des composants asynchrones (concept de *first-class*), en combinant ceci avec [le support de webpack 2 pour l'utilisation de l'importation dynamique pour séparer le code](https://webpack.js.org/guides/code-splitting-async/), tout ce que vous avez à faire est :
+
+``` js
+// changer ça :
+import Foo from './Foo.vue'
+
+// pour ça :
+const Foo = () => import('./Foo.vue')
+```
+
+Cela fonctionnera dans n'importe quel scénario si vous êtes en train de faire une application Vue uniquement pour le côté client. Toutefois, il y aura certaines limitations en l'utilisant dans du SSR. Premièrement, il faut *résoudre* tous les composants asynchrones à l'avance sur le serveur avant de faire le rendu, car sinon il y aura juste un emplacement vide dans le code HTML. Pour le côté client, il faut aussi faire cela avant de commencer l'hydratation des données, sinon il y aurait des erreurs d'incompatibilités sur le contenu.
+
+Tout cela rend un peu compliqué l'utilisation des composants asynchrones à des endroits spécifiques dans votre application (nous allons probablement améliorer cela dans le futur). Toutefois, **cela fonctionne parfaitement si vous le faites au niveau de la route** - c.-à-d. d'utiliser les composants asynchrones dans la configuration des routes - car `vue-router` ira automatiquement résoudre les composants asynchrones nécessaires au bon fonctionnement de la route. Vous devez êtes sûr d'utiliser `router.onReady` sur le serveur et le client. Nous l'avons déjà fait pour le fichier d'entrée du serveur, il ne nous reste plus que maintenant à faire de même pour le fichier d'entrée du client :
+
+``` js
+// entry-client.js
+
+import { createApp } from './app'
+
+const { app, router } = createApp()
+
+router.onReady(() => {
+  app.$mount('#app')
+})
+```
+
+Un exemple de configuration de route avec des composants asynchrones :
+
+``` js
+// router.js
+import Vue from 'vue'
+import Router from 'vue-router'
+
+Vue.use(Router)
+
+export function createRouter () {
+  return new Router({
+    mode: 'history',
+    routes: [
+      { path: '/', component: () => import('./components/Home.vue') },
+      { path: '/item/:id', component: () => import('./components/Item.vue') }
+    ]
+  })
+}
+```
diff --git a/fr/streaming.md b/fr/streaming.md
new file mode 100644
index 00000000..cfcb3d81
--- /dev/null
+++ b/fr/streaming.md
@@ -0,0 +1,33 @@
+# Streaming
+
+`vue-server-renderer` supports stream rendering out of the box, for both the base renderer and the bundle renderer. All you need to do is use `renderToStream` instead of `renderToString`:
+
+``` js
+const stream = renderer.renderToStream(context)
+```
+
+The returned value is a [Node.js stream](https://nodejs.org/api/stream.html):
+
+``` js
+let html = ''
+
+stream.on('data', data => {
+  html += data.toString()
+})
+
+stream.on('end', () => {
+  console.log(html) // render complete
+})
+
+stream.on('error', err => {
+  // handle error...
+})
+```
+
+## Streaming Caveats
+
+In stream rendering mode, data is emitted as soon as possible when the renderer traverses the Virtual DOM tree. This means we can get an earlier "first chunk" and start sending it to the client faster.
+
+However, when the first data chunk is emitted, the child components may not even be instantiated yet, neither will their lifecycle hooks get called. This means if the child components need to attach data to the render context in their lifecycle hooks, these data will not be available when the stream starts. Since a lot of the context information (like head information or inlined critical CSS) needs to be appear before the application markup, we essentially have to wait until the stream to complete before we can start making use of these context data.
+
+It is therefore **NOT** recommended to use streaming mode if you rely on context data populated by component lifecycle hooks.
diff --git a/fr/structure.md b/fr/structure.md
new file mode 100644
index 00000000..aa173c28
--- /dev/null
+++ b/fr/structure.md
@@ -0,0 +1,123 @@
+# Structure du code source
+
+## Éviter les singletons avec états
+
+Pendant l'écriture d'un code spécifique au client, on utilise le fait que notre code sera exécuté dans un nouveau contexte à chaque fois. Toutefois, le serveur Node.js est un processus qui reste actif dans le temps. Lorsque notre code sera utilisé dans ce processus, il sera exécuté une fois et sera gardé en mémoire. Ce qui signifie que si vous créé un objet singleton, il sera partagé entre toutes les requêtes entrantes.
+
+Comme nous l'avons vu dans l'exemple de base, nous avons **créé une nouvelle instance de Vue pour chaque requête**. Ce comportement est similaire à la façon dont chaque utilisateur utilisera une nouvelle instance de l'application dans son propre navigateur. Si on partageait une même instance à travers chaque requêtes, cela entraînera une pollution du *state*.
+
+Enfin, au lieu de directement créer une instance de l'application, il serait plus intéressant de créer une fonction *factory* qui pourra être utilisée à plusieurs reprises afin de créer des nouvelles instances d'application pour chaque requête :
+
+``` js
+// app.js
+const Vue = require('vue')
+
+module.exports = function createApp (context) {
+  return new Vue({
+    data: {
+      url: context.url
+    },
+    template: `<div>L'url visitée est : {{ url }}</div>`
+  })
+}
+```
+
+Et le code du serveur devient :
+
+``` js
+// server.js
+const createApp = require('./app')
+
+server.get('*', (req, res) => {
+  const context = { url: req.url }
+  const app = createApp(context)
+
+  renderer.renderToString(app, (err, html) => {
+    // gérer l'erreur...
+    res.end(html)
+  })
+})
+```
+
+La même règle s'applique aux instances du routeur, du store, ainsi qu'au bus d'événements. Au lieu de l'exporter depuis un module et de l'importer dans votre application, il faut créer une nouvelle instance dans `createApp` et l'injecter dans l'instance de Vue.
+
+> Cette contrainte peut être contournée en utilisant le moteur de rendu avec `{ runInNewContext: true }`, toutefois, cela implique un certain coût de performance car un nouveau contexte *vm* a besoin d'être créé pour chaque requête. 
+
+## Introduction à l'étape de *build*
+
+Jusqu'à présent, nous n'avons pas encore vu comment délivrer la même application Vue au client. Pour faire cela, nous avons besoin d'utiliser webpack pour empaqueter notre application Vue. En fait, nous voudrons également utiliser webpack pour empaqueter l'application Vue sur le serveur, car :
+
+- Les applications Vue sont souvent construites avec webpack et `vue-loader`, et plusieurs fonctionnalités spécifiques à webpack, comme l'import de fichiers grâce `file-loader` ou l'import de CSS grâce à `css-loader`, ne fonctionneront pas directement avec Node.js.
+
+- Bien que la dernière version de Node.js supporte entièrement les fonctionnalités d'ES2015, il faudra cependant toujours transpiler le code pour le client afin de rester compatible avec les vieux navigateurs. Ce qui implique une étape de *build* supplémentaire.
+
+L'idée est d'utiliser webpack pour empaqueter notre application pour le client et pour le serveur. Le *bundle* serveur sera requis par le serveur et utilisé pour le SSR, alors que le *bundle* client sera envoyé au navigateur pour hydrater le code HTML.
+
+![architecture](https://cloud.githubusercontent.com/assets/499550/17607895/786a415a-5fee-11e6-9c11-45a2cfdf085c.png)
+
+Nous discuterons des détails de l'installation un peu plus tard. Pour le moment, nous assumerons que nous avons déjà configuré notre projet, et que nous pouvons écrire notre code avec webpack d'activé
+
+## Structure du code avec Webpack
+
+Maintenant que nous utilisons webpack pour gérer l'application pour le serveur et le client, la majorité de notre code peut être écrite de manière universelle, tout en en pouvant utiliser toutes les fonctionnalités de webpack. Enfin, il y [a un tas de choses](./universal.md) qu'il faut garder en tête afin d'écrire du code universel.
+
+Un projet simple ressemblerait à ça :
+
+``` bash
+src
+├── components
+│   ├── Foo.vue
+│   ├── Bar.vue
+│   └── Baz.vue
+├── App.vue
+├── app.js # entrée universelle
+├── entry-client.js # exécuté seulement avec le navigateur
+└── entry-server.js # exécuté seulement avec le serveur
+```
+
+### `app.js`
+
+`app.js` est l'entrée universelle de notre application. Dans une application client, c'est dans ce fichier qu'une instance de Vue sera créée et montée directement sur le DOM. Toutefois, pour le SSR, cette responsabilité sera déléguée au fichier d'entrée pour le client. `app.js` exporte simplement la fonction `createApp` :
+
+``` js
+import Vue from 'vue'
+import App from './App.vue'
+
+// exporte une fonction factory, pour créer des nouvelles instances 
+// de l'app, du router, et du store.
+export function createApp () {
+  const app = new Vue({
+    // cette instance ne fait que le rendu du composant App
+    render: h => h(App)
+  })
+  return { app }
+}
+```
+
+### `entry-client.js`:
+
+Le fichier d'entrée du client crée l'application et la monte sur le DOM :
+
+``` js
+import { createApp } from './app'
+
+// code spécifique au client...
+
+const { app } = createApp()
+
+// en assumant que l'élément racine du template App.vue possède id="app".
+app.$mount('#app')
+```
+
+### `entry-server.js`:
+
+Le fichier d'entrée du serveur utilise l'export par défaut, qui est une fonction qui peut être appelée à plusieurs reprises pour chaque rendu. À ce moment, cette fonction ne fait pas grand chose à part créer et retourner une instance d'application - sauf plus tard, lorsqu'on utilisera le router et la pré-récupération de données ici.
+
+``` js
+import { createApp } from './app'
+
+export default context => {
+  const { app } = createApp()
+  return app
+}
+```
diff --git a/fr/universal.md b/fr/universal.md
new file mode 100644
index 00000000..f9966c22
--- /dev/null
+++ b/fr/universal.md
@@ -0,0 +1,32 @@
+# Écriture d'un code universel
+
+Avant d'aller plus loin, prenons un moment pour discuter des contraintes lors de l'écriture d'un code "universel" - qui est, un code qui fonctionne côté serveur et également côté client. En raison des différences d'API des deux plate-formes, le comportement de notre code ne pourra pas forcément être exactement le même selon l'environnement. Nous examinerons ici les choses principales dont vous avez besoin de savoir.
+
+## Réactivité des données sur le serveur
+
+Dans une application fonctionnant uniquement côté client, chaque utilisateur utilisera une nouvelle instance de l'application dans leur navigateur. Pour le rendu serveur, nous souhaitons le même comportement : chaque requête doit avoir une nouvelle instance d'application, et isolée. De ce fait, il n'y aura pas de pollution à cause de requêtes croisées. 
+
+Étant donné que le processus actuel de rendu doit être déterministe, il faudra également
+pré-récupérer des données sur le serveur - ce qui signifie que l'état de notre application sera déjà disponible avant le lancement du rendu. Cela signifie aussi que la réactivité des données sera inutile sur le serveur, et est donc désactivée par défaut. Désactiver la réactivité des données permet d'éviter un coût de performance lors de la conversion de données en objets réactifs.
+
+## Connecteurs sur le cycle de vie d'un Composant
+
+Vu qu'il n'y a pas de modifications dynamiques, de tous les connecteurs de cycle de vie, seulement `beforeCreate` et `created` seront appelées pendant le  SSR. Ce qui signifie que le code à l'intérieur des autres connecteurs de cycle de vie, tels que `beforeMount` ou `mounted` sera exécuté uniquement sur le client.
+
+## Accéder aux API spécifiques à la plate-forme
+
+Du code universel ne peut avoir accès aux API spécifiques à une plate-forme. Si votre code utilise des variables globales uniquement disponibles dans le navigateur, comme `window` ou `document`, une erreur sera lancée lors de l'exécution dans Node.js, et vice-versa.
+
+Pour les tâches partagées entre le serveur le client mais qui utilisent les différentes APIs de plate-formes, il est recommandé d'envelopper le code spécifique à la plate-forme, dans une API universelle, ou alors d'utiliser des librairies qui font cela pour vous. Par exemple, [axios](https://github.com/mzabriskie/axios) est un client HTTP qui met à disposition la même API pour le côté serveur ainsi que le côté client.
+
+Pour les APIs spécifiques au navigateur, il faudra les utiliser dans les connecteurs de cycle de vie réservés au client.
+
+Notez que si une librairie tierce n'est pas écrite dans le but d'être universelle, il peut être délicat de l'intégrer côté serveur. Il pourrait être possible de la faire fonctionner en *mockant* certaines des variables et méthodes globales, mais cela serait difficile et pourrait interférer avec le code de détection de l'environnement des autres librairies.
+
+## Directives personnalisées
+
+La plupart des directives personnalisées manipulent directement le DOM, et donc causera des erreurs pendant le SSR. Il y a deux moyens d'éviter cela :
+
+1. Préférer l'utilisations de composants comme mécanisme d'abstraction, et travailler au niveau du DOM virtuel (ex: en utilisant les fonctions de rendu).
+
+2. Si vous avez une directive personnalisée qui ne peut être facilement remplacée par des composants, il est possible de fournir un "version server" de celle-ci en utilisant l'option [`directives`](./api.md#directives) pendant la création du moteur de rendu côté serveur.