Ah comme tout serait simple si vous aviez un super pouvoir pour votre Startup. Tel un de ces héros de Hollywood, vous pourriez vous en servir pour sauver le monde et accélérer votre développement. Et bien, j’ai une bonne nouvelle et une mauvaise nouvelle. La bonne, c’est que vous avez bien un super pouvoir. La mauvaise, c’est que vous préféreriez ne pas l’avoir.

Ce super pouvoir, c’est le don d’invisibilité.

Personne ne voit votre Startup. À force d’évoluer dans l’univers des incubateurs, des investisseurs, des conférences high tech et de la French Tech, on finit par avoir l’impression que l’on est connu. Malheureusement, c’est une illusion. Cet univers est comme un univers parallèle. Dès qu’on le quitte, on n’existe plus. La Startup devient un être immatériel incapable d’interagir avec l’univers normal. D’ailleurs je parie que même votre mère ignore ce que vous faites.

Pour réellement se développer et accoucher de licornes, l’univers des Startups françaises doit réussir à se débarrasser de son don d’invisibilité. Comment ? Déjà en arrêtant de penser français. Imaginez-vous à la place d’un américain. Pour lui, une startup qui réussit en France c’est insignifiant. C’est comme si pour vous je vous disais qu’il y a une super Startup qui réussit en Malaisie. Vous vous en fichez comme de l’an 40. Pour une Startup du vieux continent, s’imaginer Européenne est le mini minimum pour vraiment décoller. En dessous de ce niveau, elle sera perçue comme une réussite locale, et restera invisible sur la scène internationale.

Vous trouverez dans cet article une procédure pas à pas pour ajouter un formulaire de contact dans un site statique Hugo, sans avoir besoin de back-end car nous allons déléguer le traitement des données à Zapier.

J’ai déjà parlé de Hugo, le générateur de sites statiques que j’utilise pour mon blog et le site de ma société. Les sites générés étant statiques, il n’y a pas de base de données ou de scripts serveurs pour gérer un formulaire de contact. Il faut donc trouver une solution alternative. En voici une possible, mais ce n’est pas la seule.

Ce dont vous allez avoir besoin

  • Bootstrap, ou au minimum la librairie de validation de formulaire ; le thème utilisé était basé sur Bootstrap, une librairie qui permet de créer des sites web plus facilement. Si votre thème n’utilise pas Bootstrap, il faudra peut-être bidouiller un peu plus.
  • Un compte Zapier pour créer le Web Hook auquel sera envoyé les données du formulaire
  • Un compte Slack pour pouvoir poster les données du formulaire ; à noter que le gros avantage d’utiliser Zapier est de pouvoir rediriger le contenu du formulaire vers pratiquement n’importe quel support : email, Slack, Google Sheets, Office 365, etc.
  • Un peu de JavaScript (eh oui on ne peut pas toujours s’en passer malheureusement)

Étape 1 : créez un WebHook sur Zapier

Commencez par créer un compte Zapier si vous n’en avez pas encore ; la bonne nouvelle, c’est que c’est gratuit tant que vous n’utilisez pas trop le service.

Cliquez sur le bouton Make a Zap!

Make a Zap!

Dans « Built-in Apps » choisissez « Webhooks ».

Zapier Webhook

Choisissez le type « Catch Hook ».

Zapier catch hook

Passez l’étape optionnelle « Pick off a child key ».

L’étape suivante, « Test Webhooks by Zapier » est importante car elle vous donne l’URL de votre Webhook. Copiez l’adresse du webhook quelque part car nous allons en avoir besoin lorsque nous créerons le formulaire.

Notez que pour l’instant vous n’avez encore jamais envoyé de données au Webhook, par conséquent le test ne marchera pas. Gardez la page web de Zapier ouverte, nous y reviendrons plus tard.

Étape 2 : créez un fichier contact.html dans le répertoire Hugo /partials de votre site

Ce fichier contiendra le code html du formulaire de contact. Ci-dessous vous trouverez l’exemple du formulaire de contact que j’ai créé.

Quel que soit le thème que vous utilisiez, le truc est d’utiliser l’URL du Webhook créé à l’étape précédente comme destination pour les données du formulaire. Pour cela, il faut adapter la ligne <form action = ...>

Dans le code ci-dessous, remplacez https://hooks.zapier.com... par l’URL de votre hook Zapier créé dans l’étape précédente.

Vérifiez également que vous avez method="POST" comme méthode pour le form.

{{ "<!-- Contact Section -->" | safeHTML }}
<section id="contact">
    <div class="container">
        <div class="row">
            <div class="col-lg-12 text-center">
           			<h3 class="section-subheading">{{ with .Site.Params.contact.subtitle }}{{ . | markdownify }}{{ end }}</h3>
           			<br>
            </div>
		    </div>
		        <div class="col-md-6 col-md-offset-3 text-left">
		            <form  action="https://hooks.zapier.com/hooks/..." method="POST" name="sentMessage" id="contactForm">
				            <div class="form-group">
				              		<input type="hidden" name="_subject" value="Form sent from page: {{ .RelPermalink }}">
				            	</div>
		                <div class="form-group">
		                    <input type="text" class="form-control" placeholder="{{ with .Site.Params.contact.form.name.text }}{{ .  | markdownify }}{{ end }}" name="name" required data-validation-required-message="{{ with .Site.Params.contact.form.name.warning }}{{ . | markdownify}}{{ end }}">
		                    <p class="help-block text-danger"></p>
		                </div>
		                <div class="form-group">
		                    <input type="email" class="form-control" placeholder="{{ with .Site.Params.contact.form.email.text }}{{ . | markdownify }}{{ end }}" name="email" required data-validation-required-message="{{ with .Site.Params.contact.form.email.warning }}{{ . | markdownify }}{{ end }}">
		                    <p class="help-block text-danger"></p>
		                </div>
		                <div class="form-group">
		                    <input type="tel" class="form-control" placeholder="{{ with .Site.Params.contact.form.phone.text }}{{ . | markdownify }}{{ end }}" name="phone">
		                    <p class="help-block text-danger"></p>
		                </div>
		                <div class="form-group">
		                    <textarea class="form-control" placeholder="{{ with .Site.Params.contact.form.message.text }}{{ . | markdownify }}{{ end }}" name="message" required data-validation-required-message="{{ with .Site.Params.contact.form.message.warning }}{{ . | markdownify }}{{ end }}"></textarea>
		                    <p class="help-block text-danger"></p>
		                </div>
		                <div class="clearfix"></div>
		                <div class="col-lg-12 text-center">
		                    <div id="success">{{ with .Site.Params.contact.success }}{{ . | markdownify }}{{ end }}</div>
		                    <input type="submit" value="{{ with .Site.Params.contact.buttonText }}{{ . | markdownify }}{{ end }}" class="btn btn-primary btn-xl">
		                </div>
                </form>
            </div>
        </div>
    </div>
</section>

Après cette étape, vous devrez bien sûr modifier le code de vos pages pour qu’elles intègrent le formulaire là où vous le souhaitez ; je ne détaille pas cette étape, si vous lisez cet article c’est que vous savez déjà comment faire.

Étape 3 : ajoutez le code JavaScript nécessaire à la validation interactive du formulaire

Vous connaissez déjà mon peu d’amour pour JavaScript, mais dans ce cas-ci c’est la seule solution que j’ai trouvé qui fonctionne. Le code est inséré directement dans la page, mais vous pouvez très bien le mettre dans un fichier sous /static/js/

<script type="text/javascript">
$(function() {

    $("input,textarea").not("[type=search]").jqBootstrapValidation({
        preventSubmit: true,
        submitError: function($form, event, errors) {
            
        },
        submitSuccess: function($form, e) {
    	    e.preventDefault();
    	
    	    var submitButton = $('input[type=submit]', $form);
    	    $.ajax({
    	      type: 'POST',
    	      url: $form.prop('action'),
    	      accept: {
    	        javascript: 'application/javascript'
    	      },
    	      data: $form.serialize(),
    	      beforeSend: function() {
				submitButton.prop('value', 'Please Wait...');
				submitButton.prop('disabled', 'disabled');
    	      }
    	    }).done(function(data) {
				submitButton.prop('value', 'Thank you, we\x27ll get back to you shortly.');
    			submitButton.prop('disabled', false);
    			hj('formSubmitSuccessful');
    	    });
        },

        filter: function() {
            return $(this).is(":visible");
        },
    });

});

 
$('#name').focus(function() {
    $('#success').html('');
});
</script> 

À noter que même sans ce bout de code JavaScript, la soumission du formulaire au Webhook fonctionnera. Par contre c’est moche ; le visiteur sera redirigé vers une page affichant le résultat technique du Webhook, ce qui n’est vraiment pas idéal.

Étape 4 : installez le module JavaScript jqBootstrapValidation

Ce module est nécessaire pour faire fonctionner le code précédent. Vous le trouverez à l’URL suivant :

http://ReactiveRaven.github.com/jqBootstrapValidation/

Copiez le fichier jqBootstrapValidation.js dans le répertoire /static/js/

Étape 5 : finissez de configurer les pages de votre site

N’oubliez pas d’intégrer le code du formulaire et le code JavaScript à vos pages. Sinon évidemment ça ne marchera pas. Selon votre formulaire de contact, il est très probable que vous deviez adapter certains détails du code. Je ne pense pas avoir modifié le code de jqBootstrapValidation mais avec le temps on oublie parfois…

Étape 6 : finissez de configurer Zapier

Je ne vais pas expliquer ce qu’il faut faire ici en détail car il y a des dizaines de solutions possibles, mais vous devrez configurer Zapier pour qu’il envoie les donnée du formulaire vers le canal de votre choix : Papier, email etc. Sans cela les données seront bloquées chez Zapier et pas très utiles.

Au final, l’action Zapier pour Slack ressemble à ceci :

Zapier Slack Action

Pour résumer…

  • J’ai créé un Webhook sur Zapier pour récupérer les données du formulaire.
  • J’ai ajouté le fichier contact.html dans le répertoire /layouts/partials du thème, avec le code du formulaire.
  • J’ai ajouté le code JavaScript nécessaire lors de la soumission du formulaire.
  • J’ai ajouté le fichier jqBootstrapValidation.js dans le répertoire /static/js/
  • J’ai fini de configurer l’action Zapier pour poster les données du Webhook sur Slack.

Voilà, j’espère que cela vous aura été utile. Comme dans tout développement de ce type, difficile de garantir que cela fonctionnera tel quel sur votre site, mais cela devrait déjà être un bon point de départ.

Ma femme se rendant à la conférence LEGO SeriousPlay début novembre, nous en avons profité pour partir en famille au Danemark. Nous sommes allés à Legoland, mais surtout nous avons visité la LEGO House, ouverte depuis peu. À la LEGO House, pas d’attractions qui remuent. L’endroit est fait pour stimuler la créativité à l’aide de la petite brique.

La première découverte est le bâtiment lui-même. Entièrement paré de blanc, sa structure ressemble à des briques LEGO géantes empilées.

LEGO House

À l’entrée dans le hall d’accueil le regard est rapidement capté par l’arbre gigantesque qui trône au milieu du bâtiment. Arbre entièrement en LEGO bien sûr, et qui fait quinze mètres de haut !

LEGO House arbre géant

Au fur et à mesure que l’on monte l’escalier central qui donne accès au début de la visite, on découvre sur chacune des branches une création qui rappelle un des univers phares de la marque. Pour moi, c’est l’univers des astronautes des années 80 qui évoque le plus de souvenirs.

LEGO espace années 80

Arrivé en haut, les véritables expériences commencent. Chaque zone offre sa propre palette d’activités. Le principe de la visite active est pleinement exploité, il n’y a pas une zone où le visiteur reste passif. Fête de Halloween oblige, le premier bac de LEGO est rempli de briques oranges pour les citrouilles et de briques blanches pour faire des fantômes. Libre à nous de passer autant de temps que nous le souhaitons sur chaque activité, il n’y a pas de temps limite.

Vers 12h la faim commençant à se faire sentir nous sommes allés au restaurant, situé au rez-de-chaussée. Pas de soucis, grâce au badge d’accueil il est possible de rentrer et sortir de la zone d’activités à volonté. Ici aussi tout est fait pour rendre l’expérience active. Par exemple chaque personne compose son menu à l’aide de quatre briques qu’il place comme il le souhaite sur un petit plateau qu’il insère dans une fente (un peu comme un CD). Un scanner va alors reconnaître les briques et envoyer directement le menu en commande. Des quatre personnes, je suis le seul dont une brique n’a pas été parfaitement reconnue par le scanner ; peu importe, dans ce cas il est possible de corriger la commande. Je ne vais pas dévoiler toute la suite pour ne pas gâcher le plaisir de la découverte. Nous avons trouvé les plats très bons, mais certaines personnes nous ont dit qu’ils n’étaient pas du goût de tout le monde. Personnellement le seul reproche que je pourrais faire est que l’attente était un peu longue.  

Une fois rassasiés, retour aux choses sérieuses.

Une activité particulièrement amusante est la possibilité pour les enfants de créer leur propre film en « stop motion » en quelques minutes. Le décor et les objets étant déjà en place, l’enfant n’a qu’à imaginer l’action et la filmer en choisissant un des trois angles de caméra prédéfinis. Nous avons fini la journée à l’aquarium virtuel. On crée un poisson en LEGO que l’on scanne. Il est alors ajouté à l’aquarium sur l’écran géant. Aussi simple que cela puisse paraître, nous avons passé énormément de temps à créer des poissons toujours plus joyeux et loufoques !

Voilà, je ne souhaite pas tout dévoiler ici, la découverte du lieu et des activités faisant partie du plaisir de la visite. C’est pourquoi je n’ai pas mis de photos des activités que nous avons réalisées. Mais nous avons tous été tellement enchantés par la LEGO House que nous y sommes retournés toute la journée deux jours plus tard. Si vous êtes fan de LEGO, impossible que vous n’aimiez pas. Cela m’a également rappelé à quel point jouer aux LEGO utilise le cerveau ; à la fin de la journée on a vraiment l’impression qu’il a utilisé toute son énergie !

LEGO House de nuit

Quelques renseignements pratiques

La LEGO House est située à Billund, au Danemark, la ville d’origine de la société LEGO. Si vous aussi vous souhaitez vous rendre à Billund, le plus simple est de prendre l’avion, de nombreuses lignes on en effet des liaisons directes avec la petite ville. Nous y sommes allés en voiture ; cependant sur le chemin nous avons eu énormément de bouchons en Allemagne, les autoroutes étant en travaux absolument partout. Du nord de la France, compter au minimum 10h de voyage en voiture.

Pour le logement nous sommes restés dans un gîte au Lalandia. Ceux-ci sont propres, confortables et bien équipés. Par contre vous devez amener vos draps et vos serviettes. Lors d’un précédent séjour nous étions restés au Legoland Hotel, mais celui-ci est plus cher et aurait besoin d’être un peu rénové.

Picture

En plus de la LEGO House, il y a le parc d’attractions Legoland, qui je dois l’avouer m’a un peu déçu ; certes certaines constructions sont impressionnantes, mais beaucoup ont vieilli et les attractions qui remuent ne sont pas trop mon truc. Il y a également la piscine à vagues avec les grands toboggans du Lalandia. Le mieux est probablement de combiner une visite de Billund avec un passage à Copenhague.

Note : je rappelle que ce blog est 100% indépendant et que je ne suis sponsorisé par absolument personne.

Je ne lis plus très souvent la presse papier, à tort ou à raison. Mais en attendant un rendez-vous client, j’ai feuilleté un magazine qui était sur la table.

Dedans, il y avait un article sur l’esprit Startup qui anime l’Elysée d’Emmanuel Macron. Et pour illustrer cet article, il y avait ce graphique.

Graphique Bad Storytelling

À priori rien de choquant. Sauf que. La pente du graphique représente une baisse de 50%, alors que la baisse réelle est d’un peu plus de 3%. Ce genre de graphique trompeur est à moitié acceptable lorsqu’au moins on indique que l’axe vertical ne démarre pas à 0, or ici aucune indication. Cet effet n’a pas été utilisé par erreur, mais pour volontairement amplifier l’impression de baisse du budget.

Mais ce n’est pas le pire. En effet, comme ce graphique illustre un article sur Emmanuel Macron, on va forcément lui attribuer cette baisse. Le problème ? Les chiffres sont ceux de 2012 à 2016, soit avant l’élection d’Emmanuel Macron. C’est du bad storytelling visuel.

Note : cet article n’est absolument pas une critique d’Emmanuel Macron, j’ai juste souhaité mettre en avant un exemple de graphique trompeur avec des données mal utilisées.

Un concurrent d’Amazon organise une réunion pour comprendre pourquoi Amazon a autant de succès.

Le responsable de la logistique dit que si Amazon réussit, c’est grâce à leur service de livraison en 1 jour ouvré. Le responsable du pricing dit que si Amazon réussit, c’est parce qu’ils ont des prix très bas. Le responsable web dit que si Amazon réussit, c’est parce que leur site est mieux fait. Le responsable produit dit que si Amazon réussit, c’est parce que ils ont la plus large offre de produits. Le responsable communication dit que si Amazon réussit, c’est parce que on parle d’eux partout, tout le temps.

Qui a raison ?

Ils ont tous raison, et ils ont tous tort. Obnubilé par sa propre vision, occupé à tirer la couverture vers lui, chaque responsable ne voit pas que si Amazon réussit mieux qu’eux, c’est parce que Amazon est meilleur en tout.

C’est le niveau d’excellence à atteindre pour qu’une startup ne reste pas une startup. Le concept de « minimum viable product » est souvent défendu par les incubateurs qui poussent les entrepreneurs à concrétiser une version de leur produit le plus vite possible. Mais la barre pour un viable product est souvent beaucoup plus haute que ce qu’ils s’imaginent. J’ai déjà entendu plusieurs fois « si vous n’avez pas honte de la première version de votre produit, c’est que vous avez attendu trop longtemps ». Bullshit. En mettant à disposition du public une première version d’un site au niveau de service ou à l’ergonomie juste « viable », vous vous tirez vous-même une balle dans le pied.

Je comprends que la première version d’un produit ne sera jamais parfaite ; d’ailleurs la perfection est par définition quelque chose d’impossible à atteindre. Mais ne vous laissez pas abuser, pour réellement décoller et non vivoter votre première version publique devra être tellement bonne qu’elle sera immédiatement compétitive.

Pour Apple, un Minimum Viable Phone aurait pu être un téléphone classique avec une partie iPod. Portés par leur marque, ils en auraient vendu des millions. Mais leur téléphone n’aurait jamais redéfini le marché.

Pour Free, un Minimum Viable Forfait aurait été un forfait téléphonique calqué sur les autres, peut-être un Euro ou deux moins cher. Mais ils n’auraient pas mis ce grand coup de pied au cul des autres opérateurs.

Je vous laisse imaginer ce qui ce serait passé si ces sociétés avaient suivi l’adage « si vous n’avez pas honte de la première version de votre produit, c’est que vous avez attendu trop longtemps ». Elles auraient mis sur le marché ce qu’on appelle en termes techniques une grosse merde.

Ces sociétés ne se sont pas contentées d’un « Minimum Viable Product » (produit minimum viable), elles ont créé un « Market Redefining Product ».

Et votre startup, son produit sera-t-il un « Minimum Viable Product » ou un « Market Redefining Product » ?