Los mejores plugins de Visual Studio Code para desarrollo web en 2021

ferenc almasi FHIdRVGets unsplash

Os voy a compartir los que son, en mi humilde opinión, los mejores y esenciales plugins de VSCode para desarrollo web. Son todos los que utilizo a diario y me van muy bien a mi.

Mi lista de indispensable es la siguiente:

GitLens

image 1

GitLens es una gozada. Si trabajas mucho con Git es casi imprescindible si quieres que te haga la vida un poco más fácil. Añade soporte de Git a Visual Studio Code y lo integra completamente en el IDE. Mira la web oficial para daros cuenta de todo lo que es capaz de hacer.

https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens

Current Line Blame
Por ejemplo, es capaz de mostrar un blame personalizable en cada línea.

Project Manager

image 2

Es normal trabajar con más de un proyecto. Esta extensión ayuda a que podamos acceder a ellos y cambiar de forma más ágil:

https://marketplace.visualstudio.com/items?itemName=alefragnani.project-manager


Live Server

image 3

Como su propio nombre indica, esta extensión creará un servidor local para poder trabajar con nuestro proyectos con la capacidad de «Live Reload»

https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&ssr=false#overview


Auto Rename Tag

image 5

Una de mis favoritas. Simplemente cambia los nombres de los dos tags a la vez cuando renombramos uno. Parece que no, pero ahorra mucho tiempo.

https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-rename-tag


Prettier

image 6

Otra de mis favoritas. Formatea el código automáticamente de prácticamente cualquier tipo. Ojo, porque es posible que tengáis que perfilar bien la configuración del plugin y puede que no os detecte del todo bien algún formato específico de plantilla.

Por suerte, es muy personalizable y tiene muchísima comunidad y usuarios, por lo que encontraréis solución a muchos problemas o dudas que os vayan surgiendo.

https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode


Docker

image 7

Esta extensión facilita el trabajo con proyectos que estén basados en contenedores de Docker. Entre muchas otras cosas, añade una barra lateral que muestra todas las imágenes, volúmenes, redes y contenedores.

https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker


JavaScript (ES6) Code Snippets

image 8

Esta extensión tiene snippets de código para JavaScript en sintaxis ES6. Soporta JavaScript y TypeScript.

Estos son unos cuantos que incluye:

image 12

https://marketplace.visualstudio.com/items?itemName=xabikos.JavaScriptSnippets


Visual Studio IntelliCode

image 9

Esta extensión oficial de Microsoft, añade funcionalidades de inteligencia artificial que nos ayudan a ser más productivos programando en Python, TypeScript, JavaScript y Java. Lo hace añadiendo IntelliSense basado en técnicas de Machine Learning.

https://marketplace.visualstudio.com/items?itemName=VisualStudioExptTeam.vscodeintellicode


Better Comments

image 10

Con Better Comments podremos crear comentarios más amigables en nuestro código.

Annotated code

https://marketplace.visualstudio.com/items?itemName=aaron-bond.better-comments


Bracket Pair Colorizer

image 11

¡Casi me emociono cuando descubrí esta pequeña joya!

Pasamos más tiempo leyendo código que escribiendo, así que toda extensión que haga más fácil la lectura, bienvenida sea. Bracket Pair Colorizer colorea con el mismo color los pares de brackets que se corresponden. Eso logra que sea más fácil identificar a qué corresponde cada uno.

Screenshot

https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer

Repaso a 2020 y metas para 2021

2021

Aunque ha sido un año totalmente distinto a lo previsto, he de decir que no me ha ido del todo mal. Tengo la suerte de trabajar en un sector en auge y que además me apasiona. Pude seguir trabajando desde el primer día de confinamiento y he comprobado que tengo la cabeza lo suficientemente centrada como para, por lo menos, no haberme vuelto loco durante estos últimos meses. 😅

Tengo presente que hay que seguir trabajando muy duro pase lo que pase. Nos levantemos con malas noticias o con buenas. Da igual. Como dice Jack Butcher en este twit:

Mi resumen de lo más destacable de este 2020

  • Me compré una casa y me mudé.
  • Me he adaptado al teletrabajo.
  • Tengo salud, y he podido quedar y disfrutar con mis amigos algún que otro rato dentro de las limitaciones. Ellos dirán, pero creo que lo he conseguido.
  • He colaborado a que la empresa donde trabajo (ACTIUM Digital) crezca en equipo y proyectos.
  • He lanzado un nuevo proyecto junto a un amigo y excompañero de trabajo: Newslead. Ha quedado chulo. Nos gusta. Pero estamos estancados en crecimiento. De momento no ha recibido la acogida que esperábamos.
  • He lanzado nuevas funcionalidades en StoryDevil, una aplicación web que creé junto a mi amigo Carles Gòdia. También seguimos algo estancados y no hemos logrado el número de usuarios que nos habría gustado conseguir.
  • Me he leído un libro nuevo. Skin in the Game, de Nicholas Taleb. Mal porque quería terminar más.
  • He escrito más en mi blog. 19 artículos.
  • He renovado mi web.
  • He aprendido algún que otro framework nuevo, como React.
  • Me adapté al uso de teclados mecánicos TKL y empecé a aficionarme bastante al tema ⌨

Uno de los problemas con los que me encuentro tras lanzar nuevos proyectos como Newslead o StoryDevil, es que nos quedamos estancados en conseguir nuevos usuarios. No logramos crear una buena campaña de marketing, o quizá no sean productos lo suficientemente buenos o bien enfocados y no nos hemos dado cuenta. Francamente, no estoy seguro.

Para este 2021 quiero aprender más de estas situaciones y evitar que se repitan. No alargar agonías durante años como hice en un pasado con YoteConozco.com. Y si algo no funciona o no creo totalmente en un proyecto, quiero dejarlo rápidamente e ir a por otra cosa.

Aunque no soy fiel seguidor de las listas y me gusta improvisar un poco porque todo cambia, sí que tengo claros algunos puntos y objetivos para este 2021 que espero que sean la base para conseguir más cosas.

  • Exponerme a más riesgos de forma honesta, generar confianza y lograr beneficios por ello.
  • Publicar algún nuevo proyecto pequeño, rápido y quizá en solitario.
  • Colaborar para que la empresa donde trabajo crezca más y siga adaptándose a la época «post-COVID» que espero que llegue en algún momento de 2021.
  • Decidir qué hacemos con StoryDevil, o logramos muchos más usuarios o acabamos con él antes de fin de año.
  • Leer más y mejor. No por obligación sino porque realmente me gusta, pero he priorizado otras cosas. Entre hoy y mañana espero terminar The Almanack of Naval Ravikant
  • Aprovechar el jardín y la BBQ, y quedar todavía más con amigos. Pasar más tiempo con ellos y dejar claro que son una prioridad por delante de un simple proyecto o tarea pendiente.
  • Aprender o mejorar en:
    • Rust
    • JAMStack
    • TailwindCSS
    • Kubernetes
    • Vue
    • Laravel
    • … y el que me caiga en gracia en cualquier momento.
  • Fabricar un teclado mecánico lo más desde 0 posible. Poder divertirme con este hobby y no acabar arruinado 🤞

Cumple con la GDPR con este simple y elegante plugin de cookies gratuito

photo 1586195831749 9fc3b289b4e4

Estos días he dedicado unas cuantas horas a buscar y probar algunos plugins JavaScript de cookies para poder poner un aviso simple, limpio, gratuito, y que cumpla con la GDPR o RGPD.

He encontrado uno que me ha gustado y cumple con lo que necesito: Cookieconsent Script

Antes de nada os recomiendo dos cosas. Leer la Guía sobre el uso de las cookies de la Agencia Española de Protección de Datos (AEPD) y no tomaros al pié de la letra todo lo que os explicaré. He interpretado la ley con el mejor criterio posible pero no soy abogado ni experto en este sentido.

Image for post
Aviso de cookies de storydevil.com

Como se intuye en la captura, es un plugin simple, fácil de integrar, y con un diseño bastante elegante. Un módulo JavaScript genérico que puede adaptarse a cualquier proyecto web sin necesidad de hacerlo dentro de un CMS complejo. Basta con tener unas nociones básicas de frontend.

No tiene formato ‘cookie wall’ de los que obligan al usuario a elegir una opción para interactuar con la web (no es algo obligatorio). Muestra un aviso en el footer con la opción de aceptar las cookies para poder instalarlas, y un botón de ajustes para que el usuario pueda elegir las que quiera y las que no.

Esto es lo que muestra la opción de configuración:

Image for post
Configurador de cookies de storydevil.com

Podemos añadir categorías de servicios y las distintas cookies que usemos para que aparezcan todas en la ventana anterior.

Cada cookie puede ser configurada para que el usuario pueda o no desactivarla. Las cookies técnicas por ejemplo no deben ser opcionales. Y también podemos hacer que el selector de activado o desactivado aparezca por defecto como más nos interese.

Por ejemplo, en este caso podemos hacer opcionales las cookies de Google Analytics.

Estos son los distintos tipos de bloqueo que podemos configurar en la variable type, ya que no están documentados:

  • dynamic-script
  • script-tag
  • wrapped
  • localcookie

Con la expresión regular “/_ga.*/” podemos hacer que controle las dos cookies que en mi caso Google Analytics v4 añadía a la web. Una llamada “_ga” y otra “ga_P5…”

Estas no deberían instalarse si el usuario no lo desea, así que tenemos que probar bien la implementación con, por ejemplo, el inspector de Google Chrome, en el apartado Aplicación > Cookies.

Image for post

Así puedes crear tu primera API REST con Deno

deno js background

No es necesario explicar los pasos para instalarlo. Están muy bien descritos en la web oficial. Yo para este ejemplo he usado VS Code, para el que existe este plugin oficial.

¿Cómo es Deno?

Deno es muy parecido a Node, pero lo que intenta hacer es ser más bueno construyendo un runtime más seguro y corrigiendo los errores de base que tenía Node. Deno es seguro por defecto. Esto significa que no tiene acceso a tu disco duro, ni a tu red. Lo tendrá únicamente si tú se lo das. Node, en cambio, tiene acceso a prácticamente todo nada más instalarlo.

Por ejemplo, si seguimos la guía oficial y ejecutamos el primer comando, veremos que funciona sin problema.

deno run https://deno.land/std/examples/welcome.ts

Pero si lo hacemos con el ejemplo que viene a continuación:

import { serve } from "https://deno.land/[email protected]/http/server.ts";
const s = serve({ port: 8000 });

console.log("http://localhost:8000/");
for await (const req of s) {
  req.respond({ body: "Hello World\n" });
}

Nos encontraremos con un error de permisos de acceso a la red:

Compile file://welcome.ts
error: Uncaught PermissionDenied: network access to "0.0.0.0:8000", run again with the --allow-net flag
    at unwrapResponse ($deno$/ops/dispatch_json.ts:43:11)
    at Object.sendSync ($deno$/ops/dispatch_json.ts:72:10)
    at Object.listen ($deno$/ops/net.ts:51:10)
    at listen ($deno$/net.ts:152:22)
    at serve (https://deno.land/[email protected]/http/server.ts:261:20)
    at file://welcome.ts:2:11

Esto sucede porque el primer ejemplo no necesita ningún tipo de acceso adicional para funcionar, pero el segundo necesita acceso a nuestra red. Deno, al tener seguridad por defecto, no nos permite hacerlo a no ser que le otorguemos permiso para ello.

En este ejemplo, basta con ejecutarlo con el parámetro –allow-net, y funcionará.

Lo mismo ocurre con los ficheros, en este caso necesitamos –allow-read

Crear una API con Deno

Qué mejor forma para empezar a jugar con Deno que creando nuestra primera API REST.

Con este pequeño tutorial voy a crear un array muy simple de películas y los 5 métodos para listar, buscar, crear, actualizar y eliminar elementos.

El primer paso es crear un fichero de arranque. En este caso app.ts. Lo primero será cargar Oak, un framework middleware para el servidor http de Deno. Oak está inspirado en Koa, un middleware para Node.js. Parece ser que siguen con el juego de palabras. Al final, nos ayuda a que escribir APIs sea más sencillo.

Es un ejemplo bastante sencillo que se explica prácticamente por si solo. El servidor escuchará por el puerto 4000 y cargará las rutas definidas en el fichero router.ts que veremos justo después. En el fichero ./api/controller.ts pondré la definición de las funciones para los distintos endpoints.

import { Application } from "https://deno.land/x/oak/mod.ts";
import router from "./router.ts";
import {
  getMovies,
  getMovie,
  createMovie,
  updateMovie,
  deleteMovie,
} from "./api/controller.ts";

const env = Deno.env.toObject();
const HOST = env.HOST || "127.0.0.1";
const PORT = env.PORT || 4000;

const app = new Application();

app.use(router.routes());
app.use(router.allowedMethods());

console.log(`API is listening on ${HOST}:${PORT}...`);
await app.listen(`${HOST}:${PORT}`);

Momento de definir las rutas en el fichero router.ts. Aquí importaremos también el Router de Oak y las definiciones que crearemos en el controller.ts

Instanciamos un Router y definimos las 5 rutas comentadas.

MétodoFunción
getMoviesDevuelve todas las películas
getMovieDevuelve una película a partir de un id
createMovieCrea una nueva película
updateMovieActualiza una película ya existente
deleteMovieElimina una película
import { Router } from "https://deno.land/x/oak/mod.ts";
import {
  getMovies,
  getMovie,
  createMovie,
  updateMovie,
  deleteMovie,
} from "./api/controller.ts";

const router = new Router();

router
  .get("/movies", getMovies)
  .get("/movie/:id", getMovie)
  .post("/movies", createMovie)
  .put("/movies/:id", updateMovie)
  .delete("/movies/:id", deleteMovie);

export default router;

Ahora es momento de crear el fichero controller.ts para definir los métodos de la API y el array con la base de datos de prueba.

interface Movie {
  id: string;
  title: string;
  rating: number;
}

Justo a continuación, creamos el array comentado:

/**
 * Sample array with movies
 */
let movies: Array<Movie> = [
  {
    id: "1",
    title: "TENET",
    rating: 10,
  },
  {
    id: "2",
    title: "No Time to Die",
    rating: 8,
  },
  {
    id: "3",
    title: "The Way Back",
    rating: 7,
  },
  {
    id: "4",
    title: "The Invisible Man",
    rating: 9,
  },
  {
    id: "5",
    title: "Onward",
    rating: 8,
  },
];

Y ahora los distintos métodos, empezando por el que lista todas las películas. Quedaría así de simple:

/**
 * Returns all the movies in database
 */
const getMovies = ({ response }: { response: any }) => {
  response.body = movies;
};

Vamos a por el siguiente, el encargado de devolver una película a partir de un ID que le podremos pasar por parámetro.

/**
 * Returns a movie by id
 */
const getMovie = ({
  params,
  response,
}: {
  params: { id: string };
  response: any;
}) => {
  const movie = movies.filter((movie) => movie.id == params.id)[0];
  if (movie) {
    response.status = 200;
    response.body = movie;
  } else {
    response.status = 404;
    response.body = { message: "404 Not found" };
  }
};

Si probamos a lanzar la petición con Postman, veremos que funciona.

image 12
Lanzamos la petición para un ID en concreto.

Le toca el turno al método createMovie para crear una película. El código es el siguiente:

/**
 * Creates a new movie
 */
const createMovie = async ({
  request,
  response,
}: {
  request: any;
  response: any;
}) => {
  const body = await request.body();
  const movie: Movie = body.value;
  movies.push(movie);
  response.body = { success: true, data: movie };
  response.status = 201;
};

Si lanzamos la petición de prueba, el servidor nos contestará con el mensaje programado.

image 14

Si a continuación lanzamos la petición para devolver todas las películas, veremos como aparece la nueva correctamente.

image 15

Es el turno del método updateMovie para actualizar una película. El código es:

/**
 * Updates an existing movie
 */
const updateMovie = async ({
  params,
  request,
  response,
}: {
  params: { id: string };
  request: any;
  response: any;
}) => {
  const movie = movies.filter((movie) => movie.id == params.id)[0];
  if (movie) {
    const body = await request.body();
    movie.title = body.value.title;
    movie.rating = body.value.rating;
    response.status = 200;
    response.body = {
      success: true,
      data: movies,
    };
  } else {
    response.status = 404;
    response.body = {
      success: false,
      message: "Movie not found",
    };
  }
};

Lanzamos la correspondiente petición PUT con Postman, y obtendremos la respuesta correcta.

image 17

Y para finalizar, solo nos queda el método deleteMovie que, en este caso, elimina una película a partir de un id. Lo que hago es utilizar el filter() para actualizar el array manteniendo todas las películas con id distinto al enviado.

/**
 * Deletes a movie by a given id
 */
const deleteMovie = ({
  params,
  response,
}: {
  params: { id: string };
  response: any;
}) => {
  movies = movies.filter((movie) => movie.id !== params.id);
  response.status = 200;
  response.body = { success: true, message: "Movie removed" };
};

Probamos con Postman…

image 19

Y efectivamente acaba de desaparecer la película con id = 1.

image 21

Puedes descargarte todo el código de este ejemplo en este repositorio de mi GitHub.

eCommerce y Google Analytics: Venderás mañana si sabes porqué lo haces (o no) hoy

photo 1563013544 824ae1b704d3 1

Este es el primero de una serie de artículos que escribiré en colaboración con Josep Maria Florista. Un gran compañero en ACTIUM Digital que se encarga del marketing digital en los proyectos propios y de nuestros clientes. Josep Maria y yo trabajamos codo con codo para que las partes de SEO y marketing digital corran acompañadas de la parte más técnica y de desarrollo de los proyectos web y eCommerce.

Por esta razón, hemos decidido aportar valor conjunto en forma de publicaciones en nuestros respectivos blogs personales, para aportar sobre un tema que nos ha causado más de un quebradero de cabeza en los últimos meses. La analítica en los eCommerce. Josep María se centra en este artículo en la parte de configuración y uso de Google Analytics y yo, en la parte más técnica así como los puntos a tener en cuenta para que todo funcione bien, las comprobaciones a realizar y los posibles errores que puedes encontrarte en el proceso.

El objetivo es eliminar errores y lograr que las transacciones se registren de la forma más exacta posible.

Saber porqué te compran (y porqué no)

¿Qué es más importante, conocer porqué un usuario no acaba comprando, o saber cuando sí lo hace? Ambas cosas. Llevas dos meses pensando en comprar esa chaqueta de 400€ que te encanta. La tienes en el carrito de la tienda .com. Decides finalizar el pedido porque, simplemente, has tenido un buen día. O te lo quitas de la cabeza porque crees que tu mujer te pone los cuernos. Somos impredecibles.

Para tomar decisiones necesitamos sacar conclusiones, y para esto necesitamos datos. Fiables y exactos. No solo el número de visitas, los clics y las páginas más visitadas. Con esto no hay suficiente. De hecho, quizá sean los datos más irrelevantes en una tienda eCommerce.

Explica Josep Maria Florista que Google Analytics se ha convertido en la herramienta indispensable para poder medir, controlar y monitorizar todo lo que sucede en nuestro site. Cuando analizamos una página web con Google Analytics nos centramos más en aspectos como qué páginas consultan, con qué dispositivos lo hacen, o desde qué fuentes nos visitan.

La gran mayoría de estos análisis se realizan sin tener un objetivo que deban alcanzar los usuarios, bien porque es una página informativa, un blog o una página que tenga una actividad comercial directa, como puede ser una empresa que ofrece servicios.

Pero… ¿Qué sucede con los eCommerce o tiendas online? Este tipo de proyectos sí tienen un claro objetivo en el que basaremos el funcionamiento de las mismas: las transacciones.

Google Analytics dispone de informes de comercio electrónico muy potentes donde podremos conocer, entre otras métricas:

  • El total de ingresos
  • La tasa de conversiòn
  • El total de transacciones
  • El valor medio del pedido
  • El listado de los productos más vendidos

Además de mostrar estos datos en todos los informes de Google Analytics, podremos analizarlos en base a la transacciones realizadas. Si tenemos un eCommerce, el uso de los informes de Comercio Electrónico es una herramienta indispensable para poder monitorizar toda la información de las transacciones y por consecuencia poder analizar y optimizarlo.

Saber captar datos (y que no se pierdan)

Para la obtención de esos datos, deben comunicarse el navegador del cliente, el servidor del eCommerce, y los módulos externos (TPV). Entre ellos y sin ninguna grieta. Todos repercuten directamente en las estadísticas de venta. Si uno falla, tendrás incongruencias en los datos.

Preparar un eCommerce para averiguar estos datos parece fácil hasta que lo intentas. Entonces, te das cuenta de que no se trata simplemente de añadir el código que te facilita Google Analytics. En un proceso de compra intervienen muchos factores técnicos que debes contemplar para que los datos de navegación y compra se registren correctamente. Si falla alguno de los componentes, tendrás ventas sin registrar.

50 ventas en la web, 48 en Analytics. ¿Qué ocurre?

Has ganado una venta, pero no sabrás porqué. En algún momento Google Analytics ha dejado de trazar al usuario, y puede que sea tu culpa (o no). Cabe la posibilidad de que el usuario tenga un bloqueador de anuncios o que haya desactivado manualmente las cookies de tu web. En cualquiera de estos casos, no será posible hacer un tracking correcto de la transacción si usamos Google Analytics integrado en el cliente. Es decir, con la librería Javascript. Para evitarlo podemos usar la integración server-side, pero dejaremos este tema para otro artículo.

A continuación, explicaré cómo configurar bien tu eCommerce para intentar que eso no ocurra. Considerar todos los escenarios y explicarte qué debes tener en cuenta para no perder información por el camino. Que los analistas de ventas tengan toda la información posible, y que el cliente sepa qué ocurre en cada transacción.

Paso 1: Configurar Google Analytics

Según cuenta Josep Maria, antes que nada debemos insertar el código de seguimiento en nuestro eCommerce, esta acción la podemos llevar a cabo mediantes plugins del CMS que utilice nuestra tienda online o con Google Tag Manager. Es importante asegurar que la etiqueta está insertada y se activa en todas las páginas de nuestro sitio web, podemos realizar la comprobación con la extensión para navegadores Google Tag Assistant.

Para poder visualizar los informes de Comercio Electrónico accederemos a la pestaña de Administración de Google Analytics y, en la columna Vistas entraremos en la Configuración de comercio electrónico para habilitarla.

Una vez activada nos aparecerá una nueva opción para Habilitar los informes de comercio electrónico mejorados, esta acción nos habilitará un nuevo informe en forma de funnel que nos permitirá analizar todo el proceso de compra de nuestra página: usuarios que acceden, visitas a productos, añadir productos a la cesta y realizar el checkout de compra. Para implementar el informe de comercio electrónico mejorado deberemos realizarlo a través de plugins del propio CMS o directamente con Google Tag Manager.

Magento, por ejemplo, permite configurarlo sin necesidad de instalar ningún otro módulo. Basta con seguir esta guía oficial.

Configuración de Google Analytics en Magento
Configuración de Google Analytics integrada en Magento 2

También podemos considerar el uso de plugins externos que añaden funcionalidades y análisis mucho más exhaustivos como la extensión Google Analytics Enhanced eCommerce UA GTM Tracking de Welt Pixel. Tiene una versión gratuita y una de pago. Con ambas podemos llegar a tener datos mucho más específicos que con la integración del Magento base, como por ejemplo el uso de cupones o los productos comparados.

Si usas WooCommerce, tienes el plugin gratuito WooCommerce Google Analytics que también integra las funcionalidades del Enhanced E-Commerce Analytics.

Otro tipo de informes que son de gran ayuda para identificar mejor el target de usuarios que acceden a nuestra página web son los informes demográficos y intereses. Estos informes son fáciles de activar, basta con acceder a la sección Audiencia > Datos demográficos e Intereses donde además podremos consultar toda esta información.

La gran mayoría de eCommerce utilizan una plataforma TPV externa para introducir los datos bancarios. Una vez verificada la compra, los usuarios accederán a la thank you page, página desde donde se envía el hit con toda la información de la compra hacia Google Analytics.

Si no realizamos ninguna configuración cuando accedamos al informe de Adquisición > Canales de captación, nos encontraremos que las ventas proceden de un referral que será en realidad la plataforma TPV, ya que ha sido el último punto de acceso a la página. Lo que ocurre es que de ser así perderemos la información real del acceso de los usuarios que han realizado una compra, así que deberemos omitir las páginas TPV como referrals de nuestra página web.

Esta acción la podemos llevar a cabo en la Administración de Google Analytics, en la columna de Propiedad > Configuración de la propiedad > Lista de exclusión de referencias. En este punto debemos excluir los dominios de los métodos de pago externos de nuestra página web como pueden ser sis.redsys.com o paypal.com.

Una vez hecho esto y activada la funcionalidad de eCommerce en Google Analytics, asegúrate de que las visitas entran en la web visualizando el estado en tiempo real del dashboard de GA.

Vista en tiempo real de visitas en Google Analytics
Vista en tiempo real de visitas en Google Analytics

Nos llegan las visitas a la web, bien!. Pero falta lo más importante, que lleguen los datos relacionados con el comportamiento dentro del propio eCommerce. Ahí es donde está la verdadera magia. Con los datos concretos de analítica eCommerce podremos saber qué ocurre desde que empieza el proceso de compra hasta que termina. Todo lo que nos lleva a conseguir más ventas en un futuro.

Primero, asegurate de que las opciones de eCommerce están activadas en tu cuenta de Google Analytics. Puedes encontrarlas en la sección de administración, y en «Ecommerce Settings»

Confirmación de ajustes para eCommerce en Google Analytics
Confirmación de ajustes para eCommerce en Google Analytics

Paso 2: Revisar el envío de datos a GA

Vamos a comprobar si todo lo hecho hasta el momento, funciona. En esta parte es muy importante que los equipos de marketing digital y los desarrolladores estén bien comunicados.

No hay mejor forma que probar con una compra lo más real posible. Prepara tu entorno de pruebas y todo lo necesario para completar una transacción. Es importante tener siempre un entorno de test disponible porque esta no será la única vez que necesites validar todo el proceso. En un software complejo, por muchos tests que tengas, todo puede fallar. Un eCommerce no es una web corporativa. Todo lo que ocurre durante un proceso de compra debe funcionar a la perfección. Una sola pieza que falle, y vas a perder dinero.

Prepara y documenta usuarios de prueba, una tarjeta de crédito e incluso cupones de descuento. Añade productos en el carrito con distintas cantidades y configuraciones. Puedes usar un generador online de datos falsos que incluye los que puedes llegar a necesitar. Selecciona un método de pago (y repite la prueba con todos los que tengas). Llega hasta el final. Y luego, haz también un pedido cancelado.

No es difícil preparar un plan de pruebas. Basta con un excel. Si tienes todo el plan documentado, te será fácil repetirlo una y otra vez. Además, podrás delegar la tarea. O mejor, automatizarla. Quiero hablar de esto en un futuro.

¿Cómo comprobar si llegan bien las compras?

Es la parte más fácil. Revisa Google Analytics y asegúrate de esto. Verás rápidamente si interpreta bien los datos del eCommerce.

Shopping Behavior Analysis de Google Analytics
Shopping Behavior Analysis de Google Analytics

No es así. ¿Qué hago?

Además de revisar la correcta configuración de Google Anaytics, debes revisar si realmente los datos se están enviando hacia los servidores de Google.

Para hacerlo, puedes usar el inspector de Chrome (o de tu otro navegador favorito) y analizar la petición enviada. Necesitas entrar en la pestanya Network, encargada de mostrar las peticiones de red, y filtrar por las que contienen «collect«. En el ejemplo de la captura, vemos una petición realizada haciendo clic en el botón de añadir producto en el carrito.

Pestaña Network del navegador Chrome para verificar el hit
Pestaña Network del navegador Chrome para verificar el hit

Paso 3: Confirmación del pago

Aunque parezca que no, esta es una de las partes más importantes. Es el paso final. Si Google Analytics no logra rastrear este paso, no se confirmará correctamenet tu venta.

A veces, la diferencia entre que sea fácil o difícil, es que el método de pago esté integrado en la web o sea un enlace externo. Podremos como ejemplo la pasarela estándar de Redsys. Esta integración puede realizarse de distintas formas. Si optamos por la más básica, el cliente saldrá de nuestra web para introducir los datos de su Visa y volverá al eCommerce cuando se confirme o cancele el pago. Aquí está el problema, que el usuario sale y tiene que volver para que Google Analytics lo sepa.

Cuando el usuario ha pagado, aparece esta pantalla. Si pulsamos continuar, volveremos al eCommerce y la venta se registrará. Si cerramos la ventana, no. ¡Ups!

Pantalla de confirmación de pago de Redsys
Pantalla de confirmación de pago de Redsys

Los métodos de pago (Redsys, Paypal, etc) tienen una URL de callback para avisarnos del resultado del pago y poder confirmar realmente la venta. Nos envían de forma cifrada los datos y el eCommerce puede validar el proceso. Esto suele ir en paralelo al tracking de Google Analytics, que se realiza en el cliente. Este segundo es el que puede perderse en el ejemplo anterior.

Hay dos formas de controlar esta parte. Garantizar el envío del tracking desde el servidor y no solo desde el cliente (porque lo hace via JavaScript) o bien configurar el TPV para que no pase por esta pantalla y evitar el maldito continuar. El tracking server-side merece un artículo dedicado, así que lo dejaré para más adelante.

Al grano. Debemos asegurar que Redsys no muestra esta pantalla y, en su lugar, redirige al cliente hacia nuestro eCommerce. Si evitamos este paso, aseguraremos que el cliente carga de vuelta nuestra web y podremos registrar la venta.

Desgraciadamente, Redsys implementa de forma distinta su TPV para cada banco, así que la opción de redirección no está siempre disponible. En muchos casos tendremos que avisar a Redsys para que realice la gestión. Estarán acostumbrados y encantados.

Un último detalle, si tu web utiliza Cloudflare, revisa también la configuración para que el callback de Redsys llegue sin problemas.

Paso 4: Probar, probar y probar

Modificaciones, plugins nuevos, cambios de última hora… Cuando modificamos nuestro eCommerce, todo puede fallar. Comprueba todo por duplicado, y prepara un plan de pruebas.

¿Qué puedo testear?

  • Compra de un producto
  • Compra de varios productos
  • Compra con un usuario registrado y otro anónimo
  • Prueba todos los métodos de pago
  • Compra de un producto con múltiples cantidades
  • Múltiples productos, múltiples cantidades
  • Añade productos al carrito desde las distintas páginas posibles (detalle, categoría, etc)
  • Compra con un total exacto (10.00€)
  • Compra más de 1.000€ (prueba los separadores de miles)
  • Compra productos con carácteres especiales en los nombres
  • Compra con descuentos
  • Compra utilizando la misma dirección como entrega y facturación (y al revés)

Contempla posibles errores

El usuario no siempre sigue el paso lógico de compra que testeas tu, así que comprueba también todos los posibles caminos y errores, como por ejemplo.

  • Refresca la pantalla de pago
  • Pulsa atrás en el navegador dentro de la pantalla de pago
  • Deja tu sesión inoperativa por 1 hora y luego continua con la compra

Queda claro que no es un tema nada fácil, verdad?

Ya puedes sincronizar extensiones y más en Visual Studio Code de forma oficial

vscode settings sync

Somos muchos los que trabajamos con distintos entornos y ordenadores. Ya sea en el trabajo, en casa, con un portátil y con PC de sobremesa. Podemos llegar a tener distintas instalaciones de Visual Studio Code y eso puede ser un problema si trabajamos con los mismos proyectos, ya que tendremos que replicar las configuraciones y extensiones que utilicemos en cada una.

Hasta ahora podíamos utilizar esta famosa extensión llamada Settings Sync que consigue hacer esto mismo. Sincronizar configuraciones, snippets, temas, iconos, workspaces, y más. Para lograrlo utiliza el Gist de tu cuenta de Github.

image 6

Como es lógico, esto habrá llamado la atención de Microsoft y han decidido añadir de serie esta funcionalidad. De forma oficial, dentro de VS Code.

Al tratarse de una opción muy nueva, todavía no está disponible en las versiones estables de Visual Code, pero ya la están testeando en la versión para Insiders. En este mismo enlace podréis ver la documentación oficial. Al parecer le faltan opciones todavía para poder substituir el plugin anteriormente mencionado, pero si se trata de una opción oficial y viendo lo bien que trata Microsoft a VS Code, estoy convencido de que acabará siendo mejor opción.

image 7

Como activar la sincronización

En primer lugar debes descargar la versión para Insiders de Visual Studio Code

Como explican en la página oficial, basta con activar la sincronización haciendo click en el icono del engranaje y seleccionando «Turn on Preferences Sync«

En este caso, la sincronización se realizará a través de vuestra cuenta de Microsoft o la de GitHub. Tras hacer login y enlazar la cuenta, VS Code empezará a sincronizar vuestra configuración en la nube.

Los atajos de teclado, como es lógico, se sincronizarán por plataforma (Mac, PC,…) aunque podemos desactivar esta limitación. Las extensiones se sincronizarán también por defecto, pudiendo desactivar extensiones concretas que no queramos sincronizar.

Muy interesante también la sincronización de la interfaz. Se incluyen, entre otros, el panel de entradas, los layouts y los comandos recientes.

Por el momento, tras unas horas de uso, puedo decir que no he notado mayor diferencia a utilizar la extensión Settings Sync, pero la configuración inicial ha sido mucho más sencilla y rápida. Como decía, habrá que esperar un poco porque al tratarse de una opción oficial de Microsoft, lo más probable es que termine siendo el método preferido.

Generar ficheros Word con Django y python-docx

Os explicaré como poder generar ficheros Word en formato .docx de forma dinámica con Django. En mi caso lo he utilizado para desarrollar una funcionalidad para StoryDevil, que permite a los usuarios exportar en .docx una serie de documentos necesarios para enviar cartas de presentación y propuestas editoriales en base a unos datos generados en la aplicación.

De esta forma, el usuario tiene ficheros editables que puede personalizar antes de generar un PDF o hacer el envío definitivo. Y esto, con Django y el paquete python-docx, es sorprendentemente sencillo.

Además, os compartiré el código que utilicé para que el documento se descargue directamente en el navegador del usuario, en lugar de almacenarse en el servidor.

image 5
Interfaz de StoryDevil con la funcionalidad que genera los .docx

Con la librería python-docx (Github y PyPI) puedes crear documentos Word y, como decía, de forma bastante sencilla. Tiene soporte para párrafos, estilos, tablas, personalizar cabecera y pié, objetos de forma, secciones, y más. Es compatible con Python 2.6, 2.7, 3.3 y 3.4. La única dependencia adicional es la librería lxml.

image 4

A modo de ejemplo, estas tres líneas son suficientes para crear un documento, añadirle un título, y un párrafo a continuación.

document = Document()
document.add_heading('Título del documento', 0)
p = document.add_paragraph('Esto es un documento Word generado con Python.')

Instalación

Como la mayoría de paquetes Python, la instalación se puede hacer con la utilidad pip o también con easy_install. Si preferimos el método manual, podemos descargar la última versión, descomprimirla, y instalar con python setup.py install.

# Instalar con pip
pip install python-docx

# Instalar con easy_install
easy_install python-docx

#Instalación manual
tar xvzf python-docx-{version}.tar.gz
cd python-docx-{version}
python setup.py install

También puedes añadir el paquete en el fichero requirements.txt de Django especificando la última versión compatible.

Django==3.0.3
...
python-docx==0.8.10

Crear el formulario para la descarga

Para este ejemplo vamos a crear un formulario sencillo con un botón que, tras pulsarlo, llamará a una vista que generará el documento y lo descargará directamente en el navegador.

Este es el formulario con un action que llamará a la URL que apunta a la vista.

<form action="{% url 'publication:export' %}" method="post" role="form">
    {% csrf_token %}
    <button type="submit" class="btn btn-success">
        <i class="fa fa-download"></i> Generar y descargar .docx
    </button>
</form>

En el fichero urls.py configuramos dicha URL con:

app_name = 'publication'
urlpatterns = [
    path('', views.publication, name='publication'),
    path('coverletter/export', views.coverletter_export, name='coverletter_export'),
    ....
]

De esta forma podemos llamar a la función url en la plantilla de Django para que cree automáticamente la URL correcta que llamará a nuestra vista.

Configurar la vista que generará el documento y la descarga

En el fichero views.py, he creado una función llamada coverletter_export tal y como se indica en el fichero urls.py.

Antes que nada, hay que importar lo necesario:

# Para la generación y descarga del fichero
import io

# Para utilizar algunas de las funciones de la librería
from docx import Document
from docx.shared import Inches, Pt
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.text import WD_BREAK

En mi caso he importado algunas funciones concretas de la API de python-docx como Inches y Pt, que permiten indicar longitudes (de párrafos por ejemplo) en pulgadas y en puntos, además de WD_ALIGN_PARAGRAPH que puedes utilizar para personalizar la alineación de los párrafos, pero debes consultar la documentación para ver qué necesitas exactamente.

Al grano, aquí va el ejemplo entero para generar un documento Word básico con un título centrado, y dos párrafos de texto.

Algunos detalles:

  • Podemos crear párrafos en blanco con add_paragraph()
  • Con add_heading() añadimos texto en un elemento de título, y con alignment = WD_ALIGN_PARAGRAPH.CENTER lo centramos.
  • Es posible que si le pasamos un texto con líneas en blanco a la función add_paragraph(), nos lo renderizará con párrafos enteros en blanco. Podemos recorrer el texto con splitlines() descartando las líneas en blanco y se renderizará como es debido.
  • También podemos modificar el espaciado entre líneas usando .paragraph_format.line_spacing e indicándole un valor float.
  • Podemos usar ‘\n’ en el texto para añadir saltos de línea.
def coverletter_export(request):
    document = Document()
 
    # Get the user's fullname
    if request.user.get_full_name():
        document_data_full_name = request.user.get_full_name()
    else:
        document_data_full_name = "[NOMBRE] [APELLIDOS]"
 
    # Print the user's name
    document_elements_heading = document.add_heading(document_data_full_name, 0)
    document_elements_heading.alignment = WD_ALIGN_PARAGRAPH.CENTER
 
    # Add empty paragraph
    document.add_paragraph()
 
    # Print biography and careerpath
    for line in document_data_biography.splitlines():
        if line:
            document_element_biography = document.add_paragraph(line)   
            document_element_biography.alignment = WD_ALIGN_PARAGRAPH.LEFT
            document_element_biography.paragraph_format.line_spacing = 1.15
 
    for line in document_data_careerpath.splitlines():
        if line:
            document_element_careerpath = document.add_paragraph(line)   
            document_element_careerpath.alignment = WD_ALIGN_PARAGRAPH.LEFT
            document_element_careerpath.paragraph_format.line_spacing = 1.15
 
    # Add empty paragraph
    document.add_paragraph()
 
    # Sincerely and name
    document.add_paragraph("Atentamente,\n" + document_data_full_name)

Descarga del documento generado

Como parte final, queda la generación del fichero docx.

En el ejemplo oficial se utiliza la función save() que guarda el fichero en el servidor.

document.save('demo.docx')

Pero en mi caso programé la siguiente función para que en lugar de guardarse en el servidor, el fichero se descargue directamente en el navegador del usuario y no se guarde ninguna copia en nuestros sistemas.

Basta con hacer lo siguiente:

# Save document to memory and download to the user's browser
document_data = io.BytesIO()
document.save(document_data)
document_data.seek(0)
response = HttpResponse(
    document_data.getvalue(),
    content_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
)
response["Content-Disposition"] = 'attachment; filename = "Carta de Presentación.docx"'
response["Content-Encoding"] = "UTF-8"
return response

Con esto deberías tener todo lo necesario para generar tus propios ficheros Word desde cualquier aplicación Python.

Creando StoryDevil: Los primeros resultados

Siempre nos ha costado mucho arrancar un proyecto y conseguir usuarios. El marketing puede llegar a tener un presupuesto infinito, y nuestra idea principal era el boostrapping. Arrancar con capital propio y sin inversiones externas.

Publicamos el proyecto a principios de febrero. Sin avisar a prácticamente nadie. Solo a nuestros amigos, conocidos, y con algún post en nuestros propios perfiles de Facebook, Twitter y LinkedIn. No queríamos salir con grandes fallos así que nos decantamos por un soft-launch.

En nuestra hoja de ruta tenemos un par de planes que empezaremos a ejecutar en breve para lograr nuevos nichos de usuarios que creemos que pueden funcionar, pero antes de llegar a ese punto necesitábamos un poco de masa de usuarios para recibir feedback real y que no sea de nuestros amigos.

Aunque todavía es muy pronto para sacar conclusiones, estos son los primeros resultados.

La prensa especializada habla de nosotros

El dia 14 de abril apareció un pequeño artículo en Wwwhatsnew sobre StoryDevil. Este fue un primer punto de inflexión que causó una considerable subida en los nuevos registros. Hasta este momento no habíamos realizado ninguna campaña de marketing ni habíamos publicitado la web en ningún sitio.

image 1

Este gráfico muestra los nuevos usuarios registrados durante los primeros días tras la aparición del artículo. En total logramos 504 usuarios nuevos en 7 días.

image 2

De estos usuarios, nos interesaba analizar cuantos de ellos terminaban el registro correctamente activando la cuenta, y cuantos entraban en la aplicación y creaban como mínimo un proyecto.

Primeros problemas, usuarios sin activar

Sorprendentemente, el proceso de registro nos funcionó mucho mejor de lo esperado y de 504 usuarios, solo 14 no activaron la cuenta.

Igualmente queríamos saber el porqué de todos los fallidos. Quizá teníamos un problema con el envío del correo de verificación, o un problema de experiencia de usuario.

A las pocas horas del día 14, empezaron a llegar algunos comentarios enviados con la herramienta Userback que tenemos instalada dentro de la aplicación. Todos (4) nos comentaron lo mismo. No les había llegado el correo de confirmación para poder activar la cuenta. Pensamos que 4 de 500 eran muy pocos, pero algo estaba sucediendo. Resultó que todos ellos usaban una direccion de @hotmail. Descubrimos un pequeño desajuste en nuestra configuración de mailing que hacía que Hotmail detectase los correos como Spam. Contactamos con todos los usuarios y les activamos manualmente la cuenta.

Es imprescindible detectar todos los problemas en las primeras fases de un proyecto porque luego, si la actividad se dispara, los fallos tienen consecuencias más graves.

Más tarde llegaron más peticiones de soporte para el resto de cuentas. Pero solo detectamos un error nuevo, usuarios que se equivocaron al escribir su dirección de correo durante el registro. Por ejemplo, escribiendo @gmail.com en lugar de @outlook.com

Empezamos a recibir feedback

Empieza una de las partes más divertidas. Recibir feedback de usarios reales y que no sean de tus amigos y por compromiso.

Tras analizar unas cuantas herramientas para tal, nos decidimos por Userback, que permite empezar con una cuenta gratuita con la que puedes poner un widget en la web o aplicación y los usuarios pueden enviarte feedback que luego recibes en un entorno web, desde el cual puedes gestionarlos como un sistema de ticketing y incidencias.

image

Durante todos estos días hemos recibido 7 tickets a través de Userback.

De estos 7 mensajes, 5 de ellos han sido comentarios con propuestas de mejora, y 2 con bugs detectados por usuarios.

image 3
Interfaz de administración de Userback

Propuestas de mejora

De entre las ideas que nos han llegado, destacamos las propuestas de:

  • Crear una sección donde guardar «Recursos» (objetos) utilizados en producciones.
  • Crear una sección con «Localizaciones» para marcar lugares en un mapa y/o añadir fotos sobre sitios donde grabar.
  • Formatos especiales para telenovelas en Latinoamérica.
  • 2 propuestas de mejoras visuales para facilitar la escritura de textos.

Errores

Estamos bastante satisfechos con este punto porque solo dos usuarios nos han contactado tras detectar un bug que hemos podido corregir de forma bastante rápida. Eran sencillos. Uno de ellos era que al intentar subir una foto de un personaje editado, éste daba error. Permitía hacerlo con nuevos personajes pero no al editarlos si estos eran de tipo «Monstruo».

Causar una muy buena impresión

Es una herramienta gratuita y los usuarios no pagan nada, pero son tus usuarios y dedican su tiempo a utilizarla. Todos son importantes. No hace falta decir que sin usuarios no hay web.

Nuestra intención es responder lo más rápido posible y hacerlo de la mejor forma. Creo que es importante causar un efecto «wow» en este sentido, y que sepan que tras la aplicación hay un equipo con ganas.

A modo de ejemplo, una imagen vale más que mil palabras. Pudimos arreglar un error detectado por un usuario en apenas 13 minutos y a las 21h de un lunes.

Image

Usuarios que se dan de baja

Por el momento, hemos tenido un total de 3 bajas. Todas realizadas en menos de 48 horas tras el registro, por lo que deducimos que estos usuarios se han percatado rápidamente que la herramienta no les encaja. A día de hoy (1 de mayo) no tenemos más bajas, aunque sí tenemos usuarios (8 en total) que tras el registro y primer día de uso, no han vuelto a entrar.

Visitas a la Wiki

StoryDevil tiene una Wiki completamente abierta donde todo el mundo puede consultar información sobre distintos aspectos de la producción cinematográfica y la escritura de guiones.

Estas son las estadísticas de acceso durante todo el mes de abril de 2020. Se notan los primeros días tras la publicación del artículo de Wwwhatsnew y luego una considerable bajada de actividad. Habrá que esperar un poco y analizar si los usuarios realmente lo utilizan a diario, de manera puntual, o bien reforzamos la estrategia SEO para que la Wiki sea un punto de entrada de usuarios y podamos convertirla en algo más global.

image 2

Cómo decir “No”. Plantillas para contestar de forma elegante

0*ShCGJ0P 9vPSSiGZ
Photo by Gemma Evans on Unsplash

El otro día se me ocurrió crear una página en Notion con una serie de plantillas de correo para responder “No” de forma educada y elegante en distintas situaciones.

1 Jnuz27RqhJTOy5JYPwC 8A

Quería ponerlas aquí pero es más cómodo mantener el repositorio en Notion por si voy añadiendo más. Si has llegado hasta aquí y quieres colaborar con alguna, no dudes en enviármela!

Aquí tenéis el enlace: https://www.notion.so/mpampols/C-mo-decir-No-496b2b29fdf74f3db855de4cb21e3a5c

Creando StoryDevil. Parte 1

Creo que será interesante escribir una serie de artículos explicando de forma totalmente transparente el proceso de creación y evolución del proyecto StoryDevil, del que soy fundador junto a Carles Gòdia.

Wireframe de una de las pantallas de StoryDevil

Carles es el típico amigo con el que compartes algo más que amistad. En mi caso, también aventuras empresariales. Empezamos YoteConozco.com en el año 2006, escribimos el guión de una película el año pasado, y publicamos StoryDevil hoy.

¿Por qué lo creamos?

Hace años que mi socio Carles se dedica, además de su profesión, a escribir, dirigir y incluso interpretar obras de teatro. Por mi parte, tras dedicarme muchos años al 3D y los VFX como hobby, empecé a escribir el guión de una película sobre una historia que llevaba gestando años.

Llegado a este punto, Carles y yo decidimos colaborar y escribir juntos el guión para otra película, una adaptación de su obra de teatro “Vecinas”. Más tarde nos dimos cuenta de que no existía ninguna herramienta online potente para juntar todo el trabajo de creación de una obra. Aquí es cuando decidimos crear StoryDevil.

Manos a la obra. ¿Cómo debía ser esta herramienta?

Un entorno para escribir debe ser amplio y limpio. Con una interfaz moderna. Enfocada a usuarios que escriben con dispositivos tipo ordenadores de sobremesa y tablets con teclados externos. No suele ser un trabajo para dispositivos smartphone.

Teníamos claro que StoryDevil sería una herramienta capaz de organizar y gestionar todo el trabajo de creación de una obra, con todos sus detalles, y de manera ordenada. Un lugar donde el creador tenga todo lo necesario para dar vida a su historia.

Nuestro otro objetivo era la formación. No encontramos ningún otro entorno web con información bien estructurada sobre cómo crear un guión. De ahí salió la idea de crear una Wiki para ordenar todos los documentos que explican cómo crear historias. Un lugar que pueda ser consultado en todo momento y, además, de forma libre y abierta para todo el mundo.

Diseño de la aplicación

Empezamos a diseñar los wireframes o retículas de la aplicación con el software Adobe XD. Hacerlo de esta manera nos otorgó una gran agilidad en poder cambiar constantemente los elementos de la interfaz para simular las funcionalidades de las distintas secciones.

Teníamos muy clara la estructura general de la aplicación, así que diseñamos de esta forma el esqueleto de todas y cada una de las secciones para validar los campos de datos a añadir, el funcionamiento de los botones y tenerlo todo muy claro antes de empezar a programar el front y el backend.

Wireframe de una de las pantallas de StoryDevil
Wireframe de una de las pantallas de StoryDevil

Mínimo Producto Viable (MVP)

Una de las cosas de las que te das cuenta en este proceso es de todo lo que sobra y no es indispensable para sacar la primera versión de un producto. Es importante no tener un listado extenso con todo lo que queremos implementar en una aplicación ideal. Teníamos claro que queríamos empezar siguiendo un MVP.

En el diseño anterior, por ejemplo, queríamos añadir la posibilidad de mercar como favoritas las ideas para las storylices. No es algo complejo, pero tampoco es indispensable y no hace más que añadir tiempo de desarrollo quizá innecesario. No definirá el futuro de la aplicación, así que puede esperar.

Tras definir todo lo que imaginamos como indispensable, terminamos con el diseño de todas las pantallas de StoryDevil.

1 Bm8GHMFB7piQTmCae97kyQ
Pantallas de StoryDevil con el software AdobeXD

Herramientras para trabajo en equipo y a distancia.

No tenemos oficina. Cada uno de nosotros tiene otro trabajo y otra casa. Nos toca crear StoryDevil completamente en remoto.

1 dYuXisjP9Ml11t VwmmE0w

Dropbox para repositorio de ficheros de trabajo, Github para el código, y Google Docs para documentación colaborativa. Estas son las tres herramientas principales que hemos utilizado.

Poder trabajar con todo el código en Github nos ha facilitado también enormemente el día a día. Allí continuamos gestionando todas las tareas, actualizamos el estado de las mismas, y guardamos todo el código que forma parte de StoryDevil. La web, la aplicación y la Wiki.

1 2uZeIVNdURqGw7wcf8zU4Q

En futuros artículos explicaré en detalle qué plataforma técnica elegimos y cómo empezamos el proceso de desarrollo del front-end y del back-end.