FP-Pages is a minimalist UI/Frontend Toolkit for building performance driven, accessibility first websites. Powered by modern Serverless, Javascript, API's and Markdown stack, with built in Netlify, Cloudflare pages and Azure coming soon integration for easy server(less) deploys. A lightweight classless
10kb/3kb(gzip)
CSS/SCSS library for style and layout FirstPaint and Eleventy a simple and easy to use next-gen static site generator.
Last active
January 31, 2022 12:33
-
-
Save shawn-sandy/1f9d7129bc300861508eb11d154ada0b to your computer and use it in GitHub Desktop.
FP-Pages
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require("fs"); | |
const Image = require("@11ty/eleventy-img"); | |
const htmlmin = require("html-minifier"); | |
const pluginRss = require("@11ty/eleventy-plugin-rss"); | |
const markdown = require("@shawnsandy/ideas/lib/markdown"); | |
const CleanCSS = require("clean-css"); | |
const eleventyNavigationPlugin = require("@11ty/eleventy-navigation"); | |
module.exports = function (eleventyConfig) { | |
eleventyConfig.setBrowserSyncConfig({ | |
notify: true, | |
open: true, | |
callbacks: { | |
ready: function (err, bs) { | |
bs.addMiddleware("*", (req, res) => { | |
const content_404 = fs.readFileSync("www/404.html"); | |
// Provides the 404 content without redirect. | |
res.write(content_404); | |
// Add 404 http status code in request header. | |
// res.writeHead(404, { "Content-Type": "text/html" }); | |
res.writeHead(404); | |
res.end(); | |
}); | |
}, | |
}, | |
}); | |
eleventyConfig.setQuietMode(true); | |
eleventyConfig.addWatchTarget("./src/sass/"); | |
eleventyConfig.addWatchTarget("./README.md"); | |
eleventyConfig.addWatchTarget("./src/js/"); | |
eleventyConfig.addPassthroughCopy("./src/css", "www/css/"); | |
eleventyConfig.addPassthroughCopy("./system/dsp/assets", "www/assets/"); | |
eleventyConfig.addPassthroughCopy("./src/images", "./images/"); | |
eleventyConfig.addPassthroughCopy("./img"); | |
eleventyConfig.addPassthroughCopy("./src/js/min", "www/js"); | |
eleventyConfig.addPassthroughCopy("./src/admin"); | |
// eleventyConfig.addPassthroughCopy("./src/robots.txt") | |
eleventyConfig.addNunjucksAsyncShortcode("image", imageShortcode); | |
// css-min filter | |
eleventyConfig.addFilter("cssmin", (code) => { | |
return new CleanCSS({}).minify(code).styles; | |
}); | |
//Minify our HTML | |
eleventyConfig.addTransform("htmlmin", (content, outputPath) => { | |
if (outputPath.endsWith(".html")) { | |
let minified = htmlmin.minify(content, { | |
useShortDoctype: true, | |
removeComments: true, | |
collapseWhitespace: true, | |
}); | |
return minified; | |
} | |
return content; | |
}); | |
eleventyConfig.addCollection("developer", (collection) => | |
collection.getFilteredByTags("developers").sort((a, b) => { | |
if (a.data.page.fileSlug > b.data.page.fileSlug) return -1; | |
else if (a.data.page.fileSlug < b.data.page.fileSlug) return 1; | |
else return 0; | |
}) | |
); | |
eleventyConfig.addPlugin(require("@shawnsandy/ideas/eleventy")); | |
eleventyConfig.addPlugin(pluginRss); | |
eleventyConfig.addPlugin(markdown); | |
// navigation | |
eleventyConfig.addPlugin(eleventyNavigationPlugin); | |
return { | |
dir: { | |
input: "src", | |
output: "www", | |
includes: "../system/_includes", | |
data: "../system/_data", | |
}, | |
templateFormats: ["njk", "html", "md"], | |
htmlTemplateEngine: "njk", | |
markdownTemplateEngine: "njk", | |
// pathPrefix: "/", | |
}; | |
}; | |
async function imageShortcode(src, alt = "", sizes = "50vw, 100vw") { | |
let metadata = await Image(src, { | |
widths: [300, 600], | |
formats: ["avif", "jpeg"], | |
}); | |
let imageAttributes = { | |
alt, | |
sizes, | |
loading: "lazy", | |
decoding: "async", | |
}; | |
// You bet we throw an error on missing alt in `imageAttributes` (alt="" works okay) | |
return Image.generateHTML(metadata, imageAttributes); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#HELLO=Hello developer | |
NODE_ENV=development | |
SITE_MAP_URL='https://www.sites.dev/sitemap.xml' | |
CONTACT_EMAIL=shawnsandy04@gmail.com | |
FORM_PROVIDER=web3forms | |
CONTACT_SUCCESS=/thank-you/ | |
CONTACT_PROVIDER=web3forms |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @ts-check | |
'use strict' | |
const take = require('lodash.take') | |
const date = new Date() | |
const dayjs = require('dayjs') | |
const relativeTime = require('dayjs/plugin/relativeTime') | |
const currentYear = () => date.getFullYear() | |
const formatDate = (date) => new Date(date).toDateString() | |
const stripHtml = (data = null) => { | |
if (data === null || data === undefined) return | |
return data.replace(/(<([^>]+)>)/gi, '') | |
} | |
const limit = ($arr = [], $limit = 3) => { | |
if ($arr.length >= 1) { | |
if (!$limit || $limit === null) { | |
return $arr | |
} | |
return take($arr, $limit) | |
} | |
return null | |
} | |
const timeAgo = (date) => { | |
dayjs.extend(relativeTime) | |
return dayjs(date).fromNow() | |
} | |
const openUrl = (url, label = null) => { | |
if (!url) { console.warn('url required'); return } | |
return `<a href="${url}" target="_blank" rel="nofollow noopener">${label || url}</a>` | |
} | |
module.exports = { | |
year: currentYear, | |
currentYear, | |
formatDate, | |
strip: stripHtml, | |
stripHtml, // deprecated use strip | |
limit, | |
timeAgo, | |
openUrl | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]--> | |
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]--> | |
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]--> | |
<!--[if gt IE 8]><!--> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"/> | |
<meta http-equiv="x-ua-compatible" content="ie=edge"/> | |
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/> | |
<script src="https://kit.fontawesome.com/e2ffdf4c70.js" crossorigin="anonymous"></script> | |
<meta name="description" content="{{ settings.description }}"/> | |
{% block head %} | |
<title>{{ settings.title }} | |
| | |
{{ title }}</title> | |
{% set css %} | |
{% include "src/css/critical.css" %} | |
{% endset %} | |
{# css #} | |
<style> | |
{{css | cssmin | safe}} | |
</style> | |
<link rel="stylesheet" href="/css/styles.css" media="all"/> | |
<link rel="stylesheet" href="/css/elements.css" media="all"/> | |
{% for styles in settings.styles %} | |
<link href="{{ styles }}" rel="stylesheet" media="all"/> | |
{% endfor %} | |
{% if stylesheets %} | |
{% for style in stylesheets %} | |
<link rel="stylesheet" href="{{ style }}" media="all"/> | |
{% endfor %} | |
{% endif %} | |
{% endblock %} | |
{# load up global macros #} | |
{% import "_macros/collections/featured.njk" as feature with context %} | |
</head> | |
<body class="{{ title | slug }}"> | |
{% block header %} | |
{% include "partials/nav.njk" %} | |
{% endblock %} | |
<header> | |
{% block cover %}{% endblock %} | |
</header> | |
{% block content %} | |
{{ content | safe }} | |
{% endblock %} | |
{% block footer %} | |
{% include "partials/footer.njk" %} | |
{% endblock %} | |
{% for js in metadata.scripts %} | |
<script src="{{ js }}"></script> | |
{% endfor %} | |
{# grab any scripts in the settings.js #} | |
{% if settings.scripts %} | |
{% for src in settings.scripts %} | |
<script src="{{ src }}"></script> | |
{% endfor %} | |
{% endif %} | |
{# load scripts data from the page #} | |
{% if scripts %} | |
{% for script in scripts %} | |
<script src="{{ script }}"></script> | |
{% endfor %} | |
{% endif %} | |
{%- if showRecaptcha and env.form_provider === "web3forms" %} | |
<script src="https://www.google.com/recaptcha/api.js?render={{ env.recaptcha_key or 'key-not-found' }}"></script> | |
<script> | |
grecaptcha.ready(function () { | |
grecaptcha | |
.execute("{{ env.recaptcha_key }}", {action: "contact"}) | |
.then(function (token) { | |
recaptchaResponse.value = token; | |
}); | |
}); | |
</script> | |
{% endif -%} | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% if env.node_env != 'production' %} | |
<script src="https://cdn.accesslint.com/accesslint-1.1.2.js"></script> | |
{% endif %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
title: A decent(ish) built in clipboard manager for Windows10 | |
subtitle: Windows10 not only has a built in clipboard manager but also gives you | |
the ability to sync your clipboard across devices | |
tags: ['posts', 'tips', 'Win10'] | |
date: 2021-05-28 | |
--- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<article role="region"> | |
<article> | |
<h3> | |
<a href="#">Sample Article</a> | |
</h3> | |
<p> | |
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Molestiae | |
assumenda odio rem maiores ad minima doloribus. Pariatur quibusdam dolorum | |
distinctio repellendus vero natus explicabo mollitia ea, nemo sunt | |
voluptatibus eaque! | |
</p> | |
<footer> | |
<p> | |
<a href="#" role="button"><span>Read more</span></a> | |
</p> | |
</footer> | |
</article> | |
<article> | |
<h3> | |
<a href="#">Sample Article</a> | |
</h3> | |
<p> | |
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Molestiae | |
assumenda odio rem maiores ad minima doloribus. Pariatur quibusdam dolorum | |
distinctio repellendus vero natus explicabo mollitia ea, nemo sunt | |
voluptatibus eaque! | |
</p> | |
<footer> | |
<p> | |
<a href="#" role="button"><span>Read more</span></a> | |
</p> | |
</footer> | |
</article> | |
<article> | |
<h3> | |
<a href="#">Sample Article</a> | |
</h3> | |
<p> | |
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Molestiae | |
assumenda odio rem maiores ad minima doloribus. Pariatur quibusdam dolorum | |
distinctio repellendus vero natus explicabo mollitia ea, nemo sunt | |
voluptatibus eaque! | |
</p> | |
<footer> | |
<p> | |
<a href="#" role="button"><span>Read more</span></a> | |
</p> | |
</footer> | |
</article> | |
<article> | |
<h3> | |
<a href="#">Sample Article</a> | |
</h3> | |
<p> | |
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Molestiae | |
assumenda odio rem maiores ad minima doloribus. Pariatur quibusdam dolorum | |
distinctio repellendus vero natus explicabo mollitia ea, nemo sunt | |
voluptatibus eaque! | |
</p> | |
<footer> | |
<p> | |
<a href="#" role="button"><span>Read more</span></a> | |
</p> | |
</footer> | |
</article> | |
<article> | |
<h3> | |
<a href="#">Sample Article</a> | |
</h3> | |
<p> | |
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Molestiae | |
assumenda odio rem maiores ad minima doloribus. Pariatur quibusdam dolorum | |
distinctio repellendus vero natus explicabo mollitia ea, nemo sunt | |
voluptatibus eaque! | |
</p> | |
<footer> | |
<p> | |
<a href="#" role="button"><span>Read more</span></a> | |
</p> | |
</footer> | |
</article> | |
</article> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% macro articles(category = 'post', collection = null) %} | |
{% set collectionArr = collections[category] | reverse %} | |
{% if collection !== null %} | |
{% set collectionArr = collection %} | |
{% endif %} | |
<article> | |
{% for content in collectionArr %} | |
<article> | |
<h3 id="{{ content.data.title | slug }}"> | |
<a href="{{ content.url }}">{{ content.data.title }}</a> | |
</h3> | |
<time datetime="{{ page.date.toLocaleString() }}"> | |
Posted: | |
{{ content.date.toUTCString() }} | |
</time> | |
<p>{{ content.data.summary }}</p> | |
<footer> | |
<a href="{{ content.url }}" role="button"> | |
<em>Continue reading</em> | |
</a> | |
</footer> | |
<hr/> | |
</article> | |
{% endfor %} | |
</article> | |
{% endmacro %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% extends "_Layout.njk" %} | |
<!-- head --> | |
{% block head %}{{ super() }} {% endblock %} | |
<!-- cover --> | |
{% block cover %} {% endblock %} | |
<!-- content --> | |
{% block content %} | |
<main> | |
<section> | |
{% if showDate %} Posted: | |
<time datetime="{{ page.date }}"> | |
{{ page.date.toDateString() }} | |
</time> | |
{% endif %} | |
{{ content | safe }} | |
</section> | |
<aside>{% include "partials/sidebar.njk" %}</aside> | |
</main> | |
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% extends "base.njk" %} | |
<!-- hide cover page --> | |
{% block cover %} | |
<section class="bg-section" style=""> | |
<h3 class="title-font quote"> | |
{{ subtitle or settings.subtitle }} | |
</h3> | |
{% endblock %} | |
{% block content %} | |
<main style="padding-top: calc(100 / 16 * 1rem)"> | |
<section> | |
{# -------------- #} | |
<article> | |
<p> | |
{{ content | safe }} | |
</p> | |
</article> | |
</section> | |
<aside> | |
{% include "partials/sidebar.njk" %} | |
</aside> | |
</main> | |
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
title: Contact Us | |
scripts: ["/js/min/form.js"] | |
eleventyNavigation: | |
key: Contact Us | |
order: 5 | |
--- | |
<h4>Contact Info</h4> | |
<p> | |
Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquid ut delectus | |
accusamus commodi officia fugit sequi? Quisquam deleniti, atque natus | |
inventore exercitationem voluptatem eius facilis maxime itaque, esse molestias | |
recusandae. | |
</p> | |
{% if env.form_provider == "netlify" %} | |
<div>{% include 'partials/contact.njk' %}</div> | |
{% elif env.form_provider == "web3forms" %} | |
<div>{% include 'partials/webform-contact.njk' %}</div> | |
{% else %} | |
<hr /> | |
<p> | |
Thanks you message, feedback, questions or suggestions, someone form our team | |
will review your email and respond as soon as possible. | |
</p> | |
<hr /> | |
{% endif %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<p>{{ hlp.11ty.noHtml(content.templateContent) | truncate(300) }}</p> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@use "../system/dsp/dist/styledictionary/scss/variables.scss"as tokens; | |
@use '@shawnsandy/first-paint/src/components/reset.scss'; | |
@use '@shawnsandy/first-paint/src/components.scss'with($render-page: true, | |
$render-type: true, | |
$render-nav: true, | |
$render-footer: true, | |
$render-main: true, | |
$render-grid: true, | |
// $render-form: true, // the form is optional | |
); | |
[data-cover] { | |
display: flex; | |
flex-direction: column; | |
height: 100vh; | |
} | |
nav, | |
footer { | |
flex-shrink: 0; | |
} | |
header { | |
display: flex; | |
flex-direction: column; | |
flex-grow: 1; | |
align-items: center; | |
justify-content: center; | |
&>[role="banner"] { | |
flex-grow: 1; | |
@include components.header-banner(); | |
min-height: 35rem | |
} | |
.fp-button-link[role=button]>em, | |
a[role=button]>em { | |
font-size: 1.4rem; | |
background-color: #fff; | |
border-radius: 6.1875rem !important; | |
text-shadow: none; | |
box-shadow: none; | |
box-shadow: 0.2rem 0.2rem 0.2rem rgba(0, 0, 0, 0.2); | |
&:hover { | |
background-color: #fff; | |
box-shadow: 0.2rem 0.5rem 0.5rem rgba(7, 0, 0, 0.2) | |
} | |
} | |
} | |
@include components.button-links(); | |
header { | |
background-color: tokens.$midnight-blue; | |
background-image: url('../images/banner-hero.svg'); | |
background-repeat: no-repeat; | |
background-position: center; | |
background-size: cover; | |
color: tokens.$white-smoke; | |
text-shadow: 0.2rem 0.2rem 0.2rem rgba(0, 0, 0, 0.2); | |
padding: 3rem 0; | |
min-height: 350rem / 16; | |
h2 { | |
font-size: 4rem; | |
} | |
>section, | |
div { | |
max-width: 70vw; | |
text-align: center; | |
margin: 0 auto; | |
} | |
margin-bottom: 4rem; | |
} | |
section[aria-label="feature"] { | |
@media (min-width: 980px) { | |
max-width: 80%; | |
margin: auto; | |
} | |
&[aria-label=feature] h3 { | |
display: block; | |
font-size: 2.5rem; | |
color: #1010b9; | |
margin-bottom: 1.5rem; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8" /> | |
<meta http-equiv="x-ua-compatible" content="ie=edge" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1" /> | |
<title>title</title> | |
<meta name="description" content="title" /> | |
<meta name="author" content="author" /> | |
<link rel="stylesheet" href="/styles/cover-page.css" /> | |
</head> | |
<body> | |
<header> | |
<nav role="navigation" aria-label="Main navigation"> | |
<section id="navigation"> | |
<h1> | |
<a href="#" aria-label="Site logo"> | |
<img src="/img/fp.svg" alt="" /><span aria-label="logo text" | |
>FirstPaint</span | |
> | |
</a> | |
</h1> | |
</section> | |
<section> | |
<ul> | |
<li><a href="#">Blog</a></li> | |
<li><a href="#">Blog</a></li> | |
<li><a href="#">Blog</a></li> | |
<li><a href="#">Blog</a></li> | |
</ul> | |
</section> | |
<section> | |
<a href="#">Blog</a> | |
<a href="#">About</a> | |
<a href="http://">Documentation</a> | |
<a href="http://">Repository</a> | |
<a href="#">Contact Us</a> | |
<a href="http://" role="button"><em>Button Link</em></a> | |
</section> | |
</nav> | |
<section role="banner"> | |
<div> | |
<!-- <img src="img/fp.svg" alt="" /> --> | |
<h2>Lightweight, Fast, Accessible, Inclusive</h2> | |
<p> | |
<span | |
>First Paint is lightweight easy to use CSS/SCSS starter library | |
for quickly scaffolding/building modern, mobile friendly | |
websites.</span | |
> | |
</p> | |
<a | |
href="#" | |
role="button" | |
aria-label="Add word, cta action, to your button title" | |
> | |
<span>Get Started</span></a | |
> | |
<a | |
href="#" | |
role="button" | |
aria-label="Add word, cta action, to your button title" | |
> | |
<strong>Get Started</strong></a | |
> | |
<a | |
href="#" | |
role="button" | |
aria-label="Add word, cta action, to your button title" | |
> | |
<em>Get Started</em></a | |
> | |
</div> | |
</section> | |
</header> | |
<!-- <script src="index.js"></script> --> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@use '@shawnsandy/first-paint/src/styles/critical.scss'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8" /> | |
<meta http-equiv="x-ua-compatible" content="ie=edge" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1" /> | |
<title>title</title> | |
<meta name="description" content="title" /> | |
<meta name="author" content="author" /> | |
<!-- load the critical styles inline --> | |
{% set css %} {% include "src/css/critical.css" %} {% endset %} | |
<!-- feed it through our cssmin filter to minify --> | |
<style> | |
{{ css | cssmin | safe }} | |
</style> | |
<link rel="stylesheet" href="/css/dashboard.css" /> | |
</head> | |
<body> | |
<section role="region" aria-label="dashboard" data-dashboard> | |
<section data-sidebar> | |
<nav | |
data-sidebar-nav | |
id="sidebar" | |
role="navigation" | |
aria-label="Main navigation" | |
data-nav | |
> | |
<section role="region" aria-label="dashboard-nav"> | |
<ul> | |
<li><a href="#">Blog</a></li> | |
<li><a href="#">Blog</a></li> | |
<li><a href="#">Blog</a></li> | |
<li><a href="#">Blog</a></li> | |
</ul> | |
</section> | |
<section data-show-mobile role="region" aria-label="Close nav"> | |
<hr /> | |
<a href="#" data-sidebar-button> | |
<span> | |
<svg | |
xmlns="http://www.w3.org/2000/svg" | |
viewBox="0 0 24 24" | |
width="24" | |
height="24" | |
> | |
<path fill="none" d="M0 0h24v24H0z" /> | |
<path | |
d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z" | |
/> | |
</svg> | |
</span> | |
</a> | |
</section> | |
</nav> | |
</section> | |
<main> | |
<nav data-mobile role="navigation" aria-label="Main navigation"> | |
<section> | |
<section data-show-mobile> | |
<a | |
role="button" | |
aria-label="Navigation button" | |
href="#sidebar" | |
data-sidebar-button | |
> | |
<small> | |
<span> | |
<svg | |
xmlns="http://www.w3.org/2000/svg" | |
viewBox="0 0 24 24" | |
width="24" | |
height="24" | |
> | |
<path fill="none" d="M0 0h24v24H0z" /> | |
<path d="M3 4h18v2H3V4zm0 7h18v2H3v-2zm0 7h18v2H3v-2z" /> | |
</svg> | |
</span> | |
</small> | |
</a> | |
</section> | |
<section data-brand=""> | |
<h1> | |
<a href="/" aria-label="Site logo"> | |
<img | |
data-show-desktop | |
data-brand | |
src="/img/fp.svg" | |
alt="" | |
/><span aria-label="logo text" data-show-desktop | |
>FirstPaint</span | |
> | |
</a> | |
</h1> | |
</section> | |
</section> | |
</nav> | |
<header> | |
<section role="banner-"> | |
<div> | |
<!-- <img src="img/fp.svg" alt="" /> --> | |
<h2>Dashboard Page</h2> | |
<hr /> | |
<p> | |
<span | |
>First Paint is lightweight easy to use CSS/SCSS starter | |
library for quickly scaffolding/building modern, mobile | |
friendly websites.</span | |
> | |
</p> | |
<p> | |
<a | |
href="#" | |
role="button" | |
aria-label="Add word, cta action, to your button title" | |
> | |
<span>Get Started</span></a | |
> | |
</p> | |
<hr /> | |
</div> | |
</section> | |
</header> | |
<section> | |
<p> | |
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Ad, | |
nostrum hic, repudiandae amet perferendis nemo debitis harum quia | |
magni numquam eius! At corrupti dignissimos, temporibus veniam eos | |
aperiam nobis corporis? | |
</p> | |
</section> | |
</main> | |
</section> | |
<!-- <script src="index.js"></script> --> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8" /> | |
<meta http-equiv="x-ua-compatible" content="ie=edge" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1" /> | |
<title>{{ settings.title }} | {{ title }}</title> | |
<meta name="description" content="{{ settings.description }}" /> | |
<meta name="author" content="{{ settings.author.name }}" /> | |
<!-- load the critical styles inline --> | |
{% set css %} {% include "src/css/critical.css" %} {% endset %} | |
<!-- feed it through our cssmin filter to minify --> | |
<style> | |
{{ css | cssmin | safe }} | |
</style> | |
<link rel="stylesheet" href="/css/dashboard.css" /> | |
</head> | |
<body> | |
<section role="region" aria-label="Dashboard application" data-dashboard> | |
<section data-sidebar>{% include "partials/nav-sidebar.njk" %}</section> | |
<main> | |
<nav data-mobile role="navigation" aria-label="Main navigation"> | |
<section> | |
<section data-show-mobile> | |
<a | |
role="button" | |
aria-label="Navigation button" | |
href="#sidebar" | |
data-sidebar-button | |
> | |
<small> | |
<span> | |
<svg | |
xmlns="http://www.w3.org/2000/svg" | |
viewBox="0 0 24 24" | |
width="24" | |
height="24" | |
> | |
<path fill="none" d="M0 0h24v24H0z" /> | |
<path d="M3 4h18v2H3V4zm0 7h18v2H3v-2zm0 7h18v2H3v-2z" /> | |
</svg> | |
</span> | |
</small> | |
</a> | |
</section> | |
<section data-brand=""> | |
<h1> | |
<a href="/" aria-label="Site logo"> | |
<span aria-label="logo text">{{ settings.title }}</span> | |
</a> | |
</h1> | |
</section> | |
</section> | |
</nav> | |
<header> | |
<section role="banner-"> | |
<div> | |
<!-- <img src="img/fp.svg" alt="" /> --> | |
<h2>{{ title }}</h2> | |
<hr /> | |
</div> | |
</section> | |
</header> | |
<section role="region" aria-label="Main content"> | |
{{ content | safe }} | |
</section> | |
</main> | |
</section> | |
<!-- <script src="index.js"></script> --> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@use '@shawnsandy/first-paint/src/styles/dashboard.scss'; | |
[data-dashboard] main { | |
width: 100%; | |
padding: 1rem; | |
} | |
[data-sidebar] strong a { | |
font-size: 1.1rem; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@use '@shawnsandy/first-paint/src/components.scss'; | |
@include components.button-links(); | |
@include components.form-elements(); | |
@include components.header-addBorders(); | |
@include components.elements-pre(); | |
a[role=button]>em { | |
filter: contrast(1.15); | |
} | |
header>section[role=banner] { | |
@media (min-width: 980px) { | |
max-width: 70%; | |
} | |
} | |
strong { | |
font-weight: 500; | |
} | |
[aria-label=feature] { | |
ul { | |
margin-left: .9rem; | |
list-style: disc; | |
margin-bottom: 1rem; | |
li+li { | |
margin-top: .5rem; | |
} | |
} | |
blockquote { | |
padding: 3rem 0; | |
} | |
} | |
nav { | |
@media (min-width: 980px) { | |
//align-items: center; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
eleventyConfig.addFilter("cssmin", function (code) { | |
return new CleanCSS({}).minify(code).styles | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require('dotenv').config() | |
module.exports = { | |
hello: process.env.HELLO || 'Hello not set, but hi, anyway 👋', | |
node_env: process.env.NODE_ENV || 'development', | |
site_map_url: process.env.SITE_MAP_URL || 'https//site.com', | |
contact_email: process.env.CONTACT_EMAIL || 'site@amce.inc', | |
contact_success: process.env.CONTACT_SUCCESS || '/thank-you', | |
form_provider: process.env.FORM_PROVIDER || null, | |
url: process.env.URL || null, | |
developer_mode: process.env.DEVELOPER_MODE || true, | |
recaptcha_key: process.env.RECAPTCHA_KEY || null, | |
repository: process.env.REPOSITORY_URL || 'https://github.com/shawn-sandy/shawnsandy-dev' | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{# grab/convert icons here https://favicon.io/favicon-converter/ #} | |
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png"/> | |
<link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png"/> | |
<link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png"/> | |
<link rel="manifest" href="/favicons/site.webmanifest"/> | |
<link rel="mask-icon" href="/favicons/safari-pinned-tab.svg" color="#5bbad5"/> | |
<meta name="msapplication-TileColor" content="#da532c"/> | |
<meta name="theme-color" content="#ffffff"/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{%- macro featuring(tag = 'posts', limit = 3) -%} | |
{%- set feature = | |
hlp.11ty.take(collections[tag], limit) -%} | |
<!-- {{ feature | length | log }} --> | |
<section> | |
<div role="list"> | |
{%- for item in feature %} | |
<div role="listitem"> | |
<h3> | |
<i class="fad fa-atom-alt"></i> | |
{{ item.data.title }} | |
</h3> | |
<p> | |
{% if item.data.summary.length -%} | |
{{ item.data.summary | | |
truncate(250) }} | |
{% else %} | |
{{ hlp.11ty.noHtml(item.templateContent) | | |
truncate(50) }} | |
{% endif -%} | |
</p> | |
</div> | |
{%- endfor %} | |
</div> | |
</section> | |
<hr/> | |
{%- endmacro -%} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{# adds a grid styled collection to the page #} | |
{# attributes tag - tag, limit - | |
number of items, words - word count #} | |
{%- macro featured(tag = 'posts', limit = | |
3, words = 200) -%} | |
{%- set feature = hlp.11ty.limit(collections[tag], limit) | | |
reverse -%} | |
<section style="margin: 3rem auto"> <div role="list"> | |
{%- for item in feature %} | |
<div role="listitem"> | |
{% if item.data.coverImage %} | |
<picture> | |
<img loading="lazy" src="{{ hlp.sharp.coverImage(item.data.coverImage) }}" alt="{{ item.data.title | slug }}" width="500" height="300"/> | |
</picture> | |
{% endif %} | |
<section> | |
<h4> | |
<a href="{{ item.url }}" title="{{ item.data.title }}"> | |
<i class="{{ item.data.icon }}"></i> | |
{{ item.data.title }} | |
</a> | |
</h4> | |
<p> | |
{{ item.data.subtitle or hlp.11ty.stripHtml(item.templateContent) | | |
truncate(words) | safe }} | |
</p> | |
</section> | |
{% if item.url %} | |
<p> | |
<a href="{{ item.url }}" role="button"> | |
<em> | |
Continue Reading | |
<i class="ti ti-arrow-right"></i> | |
</em> | |
</a> | |
</p> | |
{% endif %} | |
</div> | |
{%- endfor %} | |
</div> | |
</section> | |
{%- endmacro -%} | |
{%- macro postLinks(tag = 'posts', limit = 3) -%} | |
{%- set feature = hlp.11ty.limit(collections[tag], limit) | reverse -%} | |
<section> | |
<span> | |
<ul role="list"> | |
{%- for item in feature %} | |
<li role="listitem"> | |
{% if item.data.coverimage %} | |
<picture> | |
<img loading="lazy" src="{{ item.data.coverImage }}" alt="item.data.title | slug"/> | |
</picture> | |
{% endif %} | |
<h3> | |
<i class="{{ item.data.icon }}"></i> | |
<a href="{{ content.url }}" title="{{ item.data.title | slug }}"> | |
{{ item.data.title }} | |
</a> | |
</h3> | |
</li> | |
{%- endfor %} | |
</ul> | |
</span> | |
</section> | |
{%- endmacro -%} | |
{# display a list with image/links or title #} | |
{# attributes | |
tag - tag, limit - number of items #} | |
{%- macro postImages(tag = 'posts', limit | |
= 3) -%} | |
{%- set feature = hlp.11ty.limit(collections[tag], limit) | reverse -%} | |
<section style="margin: 2rem 0"> | |
<span> | |
<ul role="list"> | |
{%- for item in feature %} | |
<li role="listitem"> | |
<a href="" title="{{ item.data.title | slug }}"> | |
{% if item.data.coverImage %} | |
<picture> | |
<img loading="lazy" src="{{ item.data.coverImage }}" alt="Image" width="500" height="300"/> | |
</picture> | |
{% else %} | |
<h3> | |
<i class="{{ item.data.icon }}"></i> | |
<a href="{{ content.url }}" title="{{ item.data.title | slug }}"> | |
{{ item.data.title }} | |
</a> | |
</h3> | |
{% endif %} | |
</a> | |
</li> | |
{%- endfor %} | |
</ul> | |
</span> | |
</section> | |
{%- endmacro -%} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8" /> | |
<meta http-equiv="x-ua-compatible" content="ie=edge" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1" /> | |
<title>{{ settings.title }}</title> | |
<meta name="description" content="title" /> | |
<meta name="author" content="author" /> | |
<script | |
src="https://kit.fontawesome.com/e2ffdf4c70.js" | |
crossorigin="anonymous" | |
></script> | |
<!-- load the critical styles inline --> | |
{% set css %} {% include "src/css/cover-page.css" %} {% endset %} | |
<!-- feed it through our cssmin filter to minify --> | |
<style> | |
{{ css | cssmin | safe }} | |
</style> | |
</head> | |
<body> | |
<div data-cover> | |
{% include 'partials/nav.njk' %} | |
<header> | |
<section role="banner"> | |
<div> | |
<!-- <img src="img/fp.svg" alt="" /> --> | |
<h2>{{ settings.subtitle }}</h2> | |
<p> | |
<span>{{ settings.description }}</span> | |
</p> | |
<p> | |
<a href="/main" role="button" aria-label="Go to the main page"> | |
<em>Get Started</em></a | |
> | |
</p> | |
</div> | |
</section> | |
</header> | |
<footer role="contentinfo"> | |
<div> | |
<p> | |
Copyright © {{ hlp.11ty.year() }} {{ settings.author.name }} | |
All rights reserved | |
</p> | |
</div> | |
</footer> | |
</div> | |
<!-- <script src="index.js"></script> --> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @ts-check | |
const Jimp = require('jimp') | |
const fs = require('fs') | |
const img = (imgs = 'google-security-check.jpg', options = {}) => { | |
const width = options.width || 1280 | |
const height = options.width || Jimp.AUTO | |
const srcDir = options.srcDir || './assets/img/' | |
const outputDir = options.outputDir || './www/images/' | |
const quality = options.quality || 80 | |
const imageSrc = `${srcDir}${imgs}` | |
const imagePath = `${outputDir}${imgs}` | |
const force = options.force || false | |
const outputCache = options.cacheDir || './.cache/images/' | |
try { | |
if (!fs.existsSync(`${outputCache}${imgs}`) && fs.existsSync(imageSrc) || force) { | |
console.log('processing image') | |
Jimp.read(`${srcDir}${imgs}`, (err, lenna) => { | |
if (err) throw err | |
lenna | |
.resize(width, height) | |
.quality(quality) | |
.write(`${outputDir}${imgs}`) | |
.write(`${outputCache}${imgs}`) | |
}) | |
} else { | |
console.log(`Seems image already exist ${imagePath}`) | |
} | |
} catch (error) { | |
console.info(error) | |
} | |
return `/images/${imgs}` | |
} | |
module.exports = { | |
img | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% extends "base.njk" %} | |
{% block cover %} | |
{% include "partials/hero.njk" %} | |
{% endblock %} | |
{% block content %} | |
{% import "_macros/collections/featured.njk" as feature with context %} | |
{{ feature.featured() }} | |
<hr/> | |
{{ super() }} | |
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
layout: landing.njk | |
title: "Cover Page" | |
tags: "page" | |
eleventyExcludeFromCollections": true | |
feature: ["interaction", "experience", "engineering"] | |
scripts: [] | |
--- | |
<section>{%- include "./partials/quotes.html" %}</section> | |
<!-- --> | |
{% import "macros/features.njk" as feature with context %} | |
<section>{{ feature.category('experience') }}</section> | |
<hr /> | |
<section>{{ feature.category('interaction') }}</section> | |
<hr /> | |
<section>{{ feature.category('engineering') }}</section> | |
<hr /> | |
<section>{{ feature.category() }}</section> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<title>{{ settings.title }}</title> | |
<meta name="description" content="{{ settings.description }}" /> | |
<meta name="author" content="{{ settings.author.name }}" /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[build] | |
publish = "www" | |
command = "npm run build" | |
[template.environment] | |
NODE_ENV = "NODE environment" | |
SITE_MAP_URL = "https://www.xxx.com/sitemap.xml" | |
CONTACT_EMAIL = "Contact email" | |
FORM_PROVIDER = "Contact form provider (netlify/webforms)" | |
CONTACT_SUCCESS = "/thank-you (page)" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<meta property="og:title" content="{{ title or settings.title }}"/> | |
<meta property="og:description" content="{{ subtitle or settings.description }}"/> | |
<meta property="og:type" content="{{ type or 'website' }}"/> | |
<meta property="og:url" content="{{ settings.url }}{{ page.url }}"/> | |
<meta property="og:image" content="{{ settings.url }}{{ coverImage or '/images/og-cover.png' }}"/> | |
<meta property="twitter:card" content="summary_large_image"/> | |
<meta property="twitter:image" content="{{ settings.url }}{{ coverImage or '/images/og-cover.png' }}"/> | |
<meta property="twitter:site" content="{{ settings.author.twitter }}"/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
permalink: "/js/repcatcha.js" | |
eleventyExcludeFromCollections: true | |
--- | |
eleventyExcludeFromCollections: true | |
<script src="https://www.google.com/recaptcha/api.js?render=YOUR_SITE_KEY_HERE"></script> | |
<script> | |
grecaptcha.ready(function () { | |
grecaptcha | |
.execute("YOUR_SITE_KEY_HERE", { | |
action: "contact", | |
}) | |
.then(function (token) { | |
recaptchaResponse.value = token; | |
}); | |
}); | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"title": "ShawnSandy.dev", | |
"subtitle": "Design, Code, Performance, Usability, Accessibility, Inclusion", | |
"url": "https://shawnsandy.dev", | |
"description": "Design First; frontend engineer, advocate, Dad, Husband, and content creator that's crazy about design, performance, usability, accessibility empowerment, diversity, inclusion, and making the world a better place.", | |
"logo_url": "/images/nav-logo.svg", | |
"feed": { | |
"subtitle": "A UI toolkit for creating and managing design/style systems, pattern libraries, style-guides, etc", | |
"filename": "feed.xml", | |
"path": "/feed/feed.xml", | |
"id": "https://shawnsandy.dev/" | |
}, | |
"author": { | |
"name": "Shawn Sandy", | |
"email": "shawnsandy@shawnsandy.dev", | |
"twitter": "@shawnsandy" | |
}, | |
"styles": [], | |
"scripts": [ | |
"./js/min/index.min.js" | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @ts-check | |
const sharp = require('sharp') | |
const fs = require('fs') | |
const getName = (img) => { | |
const _name = img.split('.') | |
const imgName = _name[0].replace('/', '-') | |
return imgName | |
} | |
/** | |
* | |
* @param {*} imgs | |
* @param {*} options | |
* @returns | |
*/ | |
const resize = (imgs = [], options = {}) => { | |
// console.log(options) | |
const format = options.format || 'jpg' | |
const srcDir = options.srcDir || './assets/img/' | |
const outputDir = options.outputDir || './www/images/' | |
const force = options.force || false | |
if (!Array.isArray(imgs) || imgs.length < 0) { | |
console.error('Image error (please ensure img is and array)') | |
return | |
} | |
imgs.map((img, index) => { | |
// console.log(index) | |
const _name = img.split('.') | |
// const imgFormat = img.split('.').pop() | |
const getFormat = img.split('.').pop() | |
if (!options.format) { options.format = getFormat } | |
const imgName = options.name || _name[0] | |
const src = `${srcDir}${img}` | |
const suffix = options.suffix || '' | |
const image = `${outputDir}${imgName}${suffix}.${options.format}` | |
if (!fs.existsSync(src)) { | |
// console.log(image) | |
console.error('Image not found', src) | |
return null | |
} | |
if (!fs.existsSync(image) || force) { | |
sharp(`${src}`) | |
.toFormat(format) | |
.resize({ width: options.width || 1200, height: options.height || null }) | |
.toFile(`${image}`, (err, info) => { | |
if (err) console.log('Error', err) | |
if (info) console.warn('Image created', `${image}`) | |
}) | |
} | |
return true | |
}) | |
} | |
/** | |
* | |
* @param {*} imgs | |
* @param {*} options | |
* @returns | |
*/ | |
const img = (imgs = ['google-security-check.jpg'], options = {}) => { | |
if (imgs.length > 0) { | |
resize([imgs[0]], options) | |
const getFormat = imgs[0].split('.').pop() | |
if (!options.format) { options.format = getFormat } | |
const imgName = getName(imgs[0]) | |
return `/${options.imgDir || 'images'}/${imgName}${options.suffix || ''}.${options.format}` | |
} | |
return null | |
} | |
/** | |
* | |
* @param {*} imgs | |
* @param {*} options | |
* @returns | |
*/ | |
const imgSrc = (imgs = 'google-security-check.jpg', options = {}) => { | |
return `<img loading="lazy" src="${img(imgs, options)}" alt="${options.name}"/>` | |
} | |
/** | |
* | |
* @param {*} imgs | |
* @returns | |
*/ | |
const coverImage = (imgs = ['og-cover.png']) => { | |
return img(imgs, { width: 800, height: 500, format: 'webp', suffix: '-cover', force: true }) | |
} | |
module.exports = { | |
img, | |
imgSrc, | |
resize, | |
coverImage | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @use replace @import with @use | |
// as - defines the namespace for your imports | |
// with - override default variables | |
@use "@shawnsandy/first-paint/src/styles/main.scss"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<textarea role="presentation" name="" id="" cols="30"> | |
<h3>Subtitle</h3> | |
<p> | |
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Debitis asperiores | |
doloremque magnam mollitia fugiat alias explicabo eum! Dolorem obcaecati | |
laudantium commodi quis, facere aspernatur sapiente, molestias quidem | |
molestiae repellat adipisci? | |
</p> | |
</textarea | |
> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<form action="https://api.web3forms.com/submit" method="POST"> | |
<input | |
type="hidden" | |
name="apikey" | |
value="d1ee3a5e-b148-4264-a8b2-b0e68c6b39c1" | |
/> | |
<div> | |
<label for="name"> <em>Name</em></label> | |
<input | |
type="text" | |
name="name" | |
id="name" | |
autocomplete="name" | |
placeholder="Your name" | |
title="Please enter your name" | |
required | |
/> | |
</div> | |
<div> | |
<label for="email"> <em>Email</em> </label> | |
<input | |
type="email" | |
name="email" | |
id="email" | |
autocomplete="email" | |
placeholder="Your email address" | |
title="The domain portion of the email address is invalid (the portion after the @)." | |
required | |
/> | |
</div> | |
<div> | |
<label for="message"> <em>Message</em> </label> | |
<textarea | |
name="message" | |
id="message" | |
placeholder="Write your message here" | |
rows="7" | |
required | |
></textarea> | |
</div> | |
<input type="hidden" name="redirect" value="{{ env.contact_success }}" /> | |
<input type="hidden" name="recaptcha_response" id="recaptchaResponse" /> | |
<button type="submit">Submit Form</button> | |
</form> | |
<!-- recaptcha form --> | |
<script src="https://www.google.com/recaptcha/api.js?render={{ | |
env.recaptcha_key | |
}}"></script> | |
<script> | |
grecaptcha.ready(function () { | |
grecaptcha | |
.execute("{{ env.recaptcha_key }}", { | |
action: "contact", | |
}) | |
.then(function (token) { | |
recaptchaResponse.value = token; | |
}); | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment