Skip to content

Instantly share code, notes, and snippets.

/**
* Nuxt2 DatoCMS Plugin
*
* features:
* - $datocms.fetchData: lightweight isomorphic data fetching of GraphQL queries
* - $datocms.subscribeToData: real-time data updates using GraphQL queries
* - $datocms.state: { error, status, statusMessage } for data subscription
* - $datocms.toHead: alias for vue-datocms' toHead method
* - <DatocmsImage>: global alias for vue-datocms's Image component
* - <DatocmsStructuredText>: global alias for vue-datocms's StructuredText component
<template>
<ClientOnly v-if="$nuxt.isPreview">
<div role="alert">
<span>Preview mode: {{ statusMessage }}</span>
<button type="button" @click="exitPreview">
Exit preview
</button>
</div>
</ClientOnly>
</template>
@jbmoelker
jbmoelker / .eleventy.js
Created January 23, 2021 17:53
GraphQL extension for Eleventy
const queryDatoGraphQL = require('./query-dato-graphql.js');
module.exports = function (config) {
// Custom data file formats (https://www.11ty.dev/docs/data-custom/)
config.addDataExtension(
'graphql',
async (query) => await queryDatoGraphQL({ query })
);
// Base Config
@jbmoelker
jbmoelker / App.jsx
Created July 8, 2019 18:49
Component Block pattern in React
import React from 'react';
import Section from './section';
export default App = () => (
<Section>
<Section.Header>
<Section.Title> My Section </Section.Title>
</Section.Header>
<Section.Body>
Any content here
@jbmoelker
jbmoelker / paint-timings-table.js
Created October 18, 2017 08:23
Paint timings table: log performance paint metrics to the console
if ('performance' in window) {
window.addEventListener('load', function () {
var paintMetrics = performance.getEntriesByType('paint');
if (paintMetrics !== undefined && paintMetrics.length > 0){
console.table(paintMetrics.map(function(metric) {
return {
event: metric.name,
startTime: metric.startTime.toFixed(2) + ' ms',
duration: metric.duration + ' ms'
}
@jbmoelker
jbmoelker / client-hints-as-image.js
Created October 10, 2017 18:30
Serve placeholder images with Client Hints (DPR, Width, Viewport Width) as text
const request = require('request')
module.exports = () => (req, res, next) => {
const dpr = parseFloat(req.headers.dpr)
const width = toInteger(req.headers.width)
const viewportWidth = toInteger(req.headers['viewport-width'])
const imageWidth = width || Math.round(viewportWidth * dpr)
const imageHeight = Math.round(imageWidth/2)
request(`http://via.placeholder.com/${imageWidth}x${imageHeight}?text=` + [
@jbmoelker
jbmoelker / fetch-json.js
Created September 28, 2017 11:22
Fetch JSON using Promisified XMLHttpRequest
export default function fetchJson(url) {
return new Promise((resolve, reject) => {
const request = new XMLHttpRequest()
request.open('GET', url, true)
request.setRequestHeader('Accept', 'application/json')
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
try {
const json = JSON.parse(request.responseText)
resolve(json)
@jbmoelker
jbmoelker / App.js
Last active August 17, 2017 08:05
Preact Details and Summary component
import { h } from 'preact';
import { Details, Summary } from './DetailsSummary';
const App = () => (
<Details>
<Summary>This is a summary supporting <code>HTML</code></Summary>
<p>... with expandible details.</p>
<p>Based on <a href="http://html5doctor.com/summary-figcaption-element/">HTML5 details/summary elements</a>.</p>
<p>And added <a href="http://caniuse.com/#feat=details">support for browsers</a> lacking built-in support.</p>
</Details>
@jbmoelker
jbmoelker / README.md
Created March 12, 2017 14:34
Immutable caching of static assets with Express.js and Service Worker

Immutable caching of static assets with Express.js and Service Worker

This recipe revisions all asset files in a dist/assets/ directory using gulp-rev. The adds a unique content based hash to each asset file. The pattern of that hash (/.*-[0-9a-f]{10}\..*/) is then used to handle these files in Express.js and the Service Worker. Express.js sets the Cache-Control header to immutable. The Service Worker serves these files directly from cache without ever attempting the server again.

@jbmoelker
jbmoelker / load-optimizely-async.js
Created February 3, 2017 10:43
Load Optimizely async
/**
* Inline this into the <head> of your HTML document. Replace `PROJECT_ID` and optionally change timeout (now 1000ms).
*
* Based on https://help.optimizely.com/Set_Up_Optimizely/Synchronous_and_Asynchronous_snippet_loading
* Simplified for today's browsers (no `s.async` or `s.type` needed, no need to prefix with `window.`).
* Note: risk of using `document.appendChild`: https://www.paulirish.com/2011/surefire-dom-element-insertion/
*/
(function(d) {
var s = d.createElement('script');
s.src = 'https://cdn.optimizely.com/js/PROJECT_ID.js';