A presentation at JAMstack_conf San Francisco in in San Francisco, CA, USA by Ire Aderinokun
Headless Chrome & Cloudinary for progressively enhanced dynamic content on the web Ire_Aderinokun JAMstack_conf_sf 2019
73% of websites in 2006 were reliant on Javascript for their core functionality
😕 Performance 😕 Accessibility 😕 Progressive Enhancement
We can use Javascript and the JAMstack to improve Javascript
💻 Frontend Developer & Cofounder, BuyCoins # Lagos, Nigeria Google Web Expert & Cloudinary Media Expert Writer, bitsofco.de
😕
😕 Javascript disabled 😕 Slow connections 😕 Emails, READMEs, etc
🤔
💡
😕 😊
const puppeteer = require(‘puppeteer’); const browser = await puppeteer.launch({ defaultViewport: { width: 800, height: 800, isLandscape: true } }); const page = await browser.newPage(); await page.goto( embedUrl, { waitUntil: ‘networkidle2’ } ); const screenshot = await page.screenshot({ omitBackground: true, encoding: ‘binary’ }); await browser.close();
const puppeteer = require(‘puppeteer’); const browser = await puppeteer.launch({ defaultViewport: { width: 800, height: 800, isLandscape: true } }); const page = await browser.newPage(); await page.goto( embedUrl, { waitUntil: ‘networkidle2’ } ); const screenshot = await page.screenshot({ omitBackground: true, encoding: ‘binary’ }); await browser.close();
const puppeteer = require(‘puppeteer’); const browser = await puppeteer.launch({ defaultViewport: { width: 800, height: 800, isLandscape: true } }); const page = await browser.newPage(); await page.goto( embedUrl, { waitUntil: ‘networkidle2’ } ); const screenshot = await page.screenshot({ omitBackground: true, encoding: ‘binary’ }); await browser.close();
const puppeteer = require(‘puppeteer’); const browser = await puppeteer.launch({ defaultViewport: { width: 800, height: 800, isLandscape: true } }); const page = await browser.newPage(); await page.goto( embedUrl, { waitUntil: ‘networkidle2’ } ); const screenshot = await page.screenshot({ omitBackground: true, encoding: ‘binary’ }); await browser.close();
const cloudinary = require(‘cloudinary’).v2; cloudinary.config(/*” config here */$); cloudinary.uploader.upload_stream((error, result) =>& { if (error) reject(error) return result.secure_url; }).end(screenshot);
const cloudinary = require(‘cloudinary’).v2; cloudinary.config(/*” config here */$); cloudinary.uploader.upload_stream((error, result) =>& { if (error) reject(error) return result.secure_url; }).end(screenshot);
const cloudinary = require(‘cloudinary’).v2; cloudinary.config(/*” config here */$); cloudinary.uploader.upload_stream((error, result) =>& { if (error) reject(error) return result.secure_url; }).end(screenshot);
const cloudinary = require(‘cloudinary’).v2; cloudinary.config(/*” config here */$); cloudinary.uploader.upload_stream((error, result) =>& { if (error) reject(error) return result.secure_url; }).end(screenshot);
JAMstackifying
JAMstackifying
exports.handler = async (event, context) =>& { const const const const params = JSON.parse(event.body); feature = params.feature; periods = params.periods; a11yColours = params.a11yColours; try { const screenshot = await takeScreenshot(feature, periods, a11yColours); const image = await uploadScreenshot(feature, screenshot); return { statusCode: 200, body: JSON.stringify(image) }; } catch (err) { return { statusCode: 500, body: err.toString() } } };
Thank you! 🌐 Where to find me 📚 Further reading & sources • ireaderinokun.com • http://news.bbc.co.uk/2/hi/technology/ 6210068.stm • bitsofco.de • • @ireaderinokun https://bitsofco.de/using-a-headlessbrowser-to-capture-page-screenshots/ • https://bitsofco.de/how-to-upload-ascreenshot-from-puppeteer-tocloudinary/ ⭐ Use the embed • caniuse.bitsofco.de
Services like Puppeteer give us the power of headless browsers, which give us to power to do things like dynamically capture screenshots of web pages. This can be incredibly useful for creating static image fallbacks of content that would otherwise only be accessible with Javascript enabled.
In this talk, I’ll show how I used Puppeteer and Cloudinary to create fallback images for the dynamic embed of CanIUse compatibility tables I created. Together we’ll create a tiny microservice that leverages these technologies and we’ll see how it all fits together to create the final product.