├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── custom.md │ └── feature_request.md ├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── gatsby-browser.js ├── gatsby-config.js ├── gatsby-node.js ├── gatsby-ssr.js ├── now.json ├── package.json ├── patches └── victormono+1.3.1.patch ├── posts ├── 2016 │ ├── 10 │ │ └── hello-world │ │ │ └── 24 │ │ │ └── index.md │ ├── 11 │ │ ├── 13 │ │ │ └── freecodecamp │ │ │ │ └── index.md │ │ └── 14 │ │ │ └── vba-ide-export │ │ │ └── index.md │ └── 12 │ │ ├── 17 │ │ └── starting-again-with-jekyll │ │ │ ├── base-jekyll-project.png │ │ │ ├── base-jekyll-site.png │ │ │ ├── dem-commits.png │ │ │ ├── index.md │ │ │ └── jekyll-logo.png │ │ ├── 03 │ │ └── first-vscode-extension │ │ │ ├── index.md │ │ │ ├── marketplace-extensions-management.png │ │ │ ├── visual-studio-marketplace.png │ │ │ ├── vsce-publish.png │ │ │ └── yeoman-err.png │ │ └── 05 │ │ └── job-hunting │ │ ├── index.md │ │ ├── shady-recruiter-middle-man.jpg │ │ └── stress-office.jpg ├── 2017 │ ├── 01 │ │ ├── 28 │ │ │ └── twitter-bot-bootstrap │ │ │ │ └── index.md │ │ ├── 04 │ │ │ └── twitter-mctwitbot │ │ │ │ └── index.md │ │ └── 05 │ │ │ └── git-and-github │ │ │ ├── fork-a-repo.png │ │ │ ├── git-logo.jpg │ │ │ ├── index.md │ │ │ └── open-a-pull-request.png │ ├── 03 │ │ └── 15 │ │ │ └── code-life-balance │ │ │ ├── fccbreakdown.jpg │ │ │ ├── gollum.jpg │ │ │ └── index.md │ ├── 05 │ │ ├── 23 │ │ │ └── twitter-bot-playground │ │ │ │ └── index.md │ │ └── 31 │ │ │ └── gets-better-with-git │ │ │ └── index.md │ └── 06 │ │ ├── 30 │ │ └── git-allow-unrelated-histories │ │ │ ├── git-compare-after.png │ │ │ ├── git-compare.png │ │ │ └── index.md │ │ └── 01 │ │ └── beginner-to-git-aliases │ │ └── index.md ├── 2018 │ ├── 11 │ │ ├── 25 │ │ │ └── graphcms-to-gatsby │ │ │ │ └── index.mdx │ │ ├── 29 │ │ │ └── gatsby-starter-to-styled-components │ │ │ │ └── index.mdx │ │ └── 30 │ │ │ └── job-hunt-dev-project │ │ │ ├── cover.jpg │ │ │ ├── index.md │ │ │ └── jobsite-cv.jpg │ ├── 12 │ │ └── 24 │ │ │ └── wsl-bootstrap-2019 │ │ │ └── index.md │ ├── 01 │ │ └── 13 │ │ │ └── wsl-bootstrap │ │ │ ├── bash-dotfiles.png │ │ │ ├── bash-wrong-perms.png │ │ │ ├── index.md │ │ │ └── upgrade-yes.png │ ├── 02 │ │ └── 27 │ │ │ └── make-time-for-100doc │ │ │ ├── index.md │ │ │ ├── wakatime-stats.png │ │ │ └── weight-gain.png │ ├── 04 │ │ └── 03 │ │ │ └── styled-components │ │ │ └── index.md │ ├── 05 │ │ ├── 22 │ │ │ └── react-context-api-with-gatsby │ │ │ │ └── index.md │ │ └── 28 │ │ │ └── travis-ci │ │ │ └── index.md │ └── 09 │ │ └── 08 │ │ └── react-context-api │ │ └── index.md ├── 2019 │ ├── 10 │ │ └── 31 │ │ │ └── build-an-mdx-blog │ │ │ ├── draw-a-horse-quincy-tweet.png │ │ │ └── index.mdx │ ├── 11 │ │ └── 06 │ │ │ └── react-advanced-london-2019 │ │ │ ├── anything.png │ │ │ └── index.mdx │ ├── 01 │ │ └── 27 │ │ │ └── multiple-git-profiles │ │ │ └── index.md │ ├── 03 │ │ ├── 24 │ │ │ └── custom-gatsby-metadata-hook │ │ │ │ ├── compareLayout.png │ │ │ │ ├── compareSEO.png │ │ │ │ └── index.mdx │ │ └── 09 │ │ │ └── testing-mdx │ │ │ ├── highlightVLive.png │ │ │ ├── index.mdx │ │ │ └── index.png │ ├── 04 │ │ ├── 01 │ │ │ └── update-wsl-from-18.04-18.10 │ │ │ │ ├── defaultRelaeaseUpgrader.png │ │ │ │ ├── derp-install.gif │ │ │ │ ├── index.mdx │ │ │ │ ├── noLtsUpgrade.png │ │ │ │ ├── normalRelaeaseUpgrader.png │ │ │ │ └── updateComlpete.png │ │ └── 09 │ │ │ └── convert-gatsby-default-blog-to-mdx │ │ │ └── index.mdx │ └── 07 │ │ └── 19 │ │ └── jamstack-london-2019 │ │ └── index.mdx ├── 2020 │ ├── 01 │ │ ├── 28 │ │ │ └── update-wsl-ubuntu-from-18.10-to-19.10 │ │ │ │ ├── 01.current-version.png │ │ │ │ ├── 02.do-release-upgrade.png │ │ │ │ ├── 03.release-upgrades-normal.png │ │ │ │ ├── 04.release-upgrade-for-realsies.png │ │ │ │ ├── 05.upgrade-confirmation.png │ │ │ │ ├── 06.config-libc6.png │ │ │ │ ├── 07.lxd-warning.png │ │ │ │ ├── 08.openssh-servier-config.png │ │ │ │ ├── 09.release-upgrades-config.png │ │ │ │ ├── 10.finish-up-install.png │ │ │ │ ├── 11.restart-prompt.png │ │ │ │ ├── 12.finish-upgrade.png │ │ │ │ ├── 13.press-x.png │ │ │ │ ├── 14.done.png │ │ │ │ ├── index.mdx │ │ │ │ └── updateComlpete.png │ │ └── 02 │ │ │ └── track-custom-events-with-fathom-analytics │ │ │ └── index.mdx │ ├── 02 │ │ ├── 13 │ │ │ └── smooth-scroll-toc-gatsby │ │ │ │ └── index.mdx │ │ └── 06 │ │ │ └── globally-style-gatsby-styled-components │ │ │ ├── index.mdx │ │ │ └── reset-page.png │ ├── 04 │ │ ├── 16 │ │ │ └── fathom-create-custom-domain │ │ │ │ ├── create-new-dns-record-netlify.png │ │ │ │ ├── fathom-dns-record-for-site.png │ │ │ │ ├── index.mdx │ │ │ │ └── pick-custom-domain-in-site-settings.png │ │ ├── 18 │ │ │ └── add-tracking-links-to-your-markdown │ │ │ │ ├── index.mdx │ │ │ │ └── url-with-goalid-showing.png │ │ ├── 19 │ │ │ └── url-shortener-with-nowsh │ │ │ │ ├── index.mdx │ │ │ │ ├── vercel-domains-settings.png │ │ │ │ └── vercel-project-overview.png │ │ ├── 25 │ │ │ └── custom-email-domain-with-now │ │ │ │ └── index.mdx │ │ ├── 27 │ │ │ ├── a-digital-garden │ │ │ │ └── index.mdx │ │ │ └── continus-deployment │ │ │ │ └── index.mdx │ │ └── 30 │ │ │ ├── large-md-assets-to-cdn │ │ │ └── index.mdx │ │ │ └── serverless-og-images │ │ │ └── index.mdx │ └── 05 │ │ ├── 02 │ │ ├── css-variables-dark-mode │ │ │ └── index.mdx │ │ └── moving-from-now-to-netlify │ │ │ └── index.mdx │ │ ├── 04 │ │ ├── patching-packages │ │ │ └── index.mdx │ │ └── react-seo-component │ │ │ └── index.mdx │ │ └── 09 │ │ ├── css-resources │ │ ├── circleImages.jpg │ │ ├── desaturatingImages.jpg │ │ └── index.mdx │ │ └── vscode-snippets │ │ └── index.mdx └── private │ ├── convert-gatsby-starter-blog-to-mdx-part-two │ ├── index.mdx │ └── index.mdx~HEAD │ ├── creat-a-html-auth-form │ ├── index.mdx │ └── like-a-psychopath.png │ ├── create-a-video-overlay-with-hooks │ └── index.mdx │ ├── fish-shell-introduction │ └── index.mdx │ ├── javascript-snippets │ └── index.mdx │ ├── preact-getting-started │ └── index.mdx │ ├── styled-components-resources │ └── index.mdx │ ├── track-custom-events-with-google-analytics │ └── index.mdx │ ├── why-is-anything-intimidating │ └── index.md │ └── yak-shaving │ └── index.mdx ├── renovate.json ├── root-wrapper.js ├── src ├── components │ ├── dump.js │ ├── header.js │ ├── layout.js │ ├── page-elements │ │ ├── a.js │ │ ├── blockquote.js │ │ ├── br.js │ │ ├── code.js │ │ ├── div.js │ │ ├── h1.js │ │ ├── h2.js │ │ ├── h3.js │ │ ├── h4.js │ │ ├── hr.js │ │ ├── img.js │ │ ├── index.js │ │ ├── inline-code.js │ │ ├── li.js │ │ ├── linked-headers.js │ │ ├── p.js │ │ ├── small.js │ │ ├── table.js │ │ └── ul.js │ ├── post-reactions.js │ ├── share.js │ └── shared.js ├── contexts │ └── event-tracking.js ├── hooks │ ├── use-local-storage.js │ └── use-site-metadata.js ├── html.js ├── pages │ ├── 404.js │ └── index.js ├── templates │ └── post-template.js ├── theme │ └── global-style.js └── utils │ └── copy-to-clipboard.js ├── static ├── angry.png ├── default-site-image.jpg ├── favicon.png ├── funny.png ├── love.png ├── moon.svg ├── sun.svg ├── surprised.png └── thumbs-up.png └── yarn.lock /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # project deps 2 | node_modules 3 | .cache 4 | 5 | # build 6 | public 7 | 8 | # Other 9 | .DS_Store 10 | yarn-error.log 11 | 12 | # Local Netlify folder 13 | .netlify 14 | 15 | # .env files 16 | .env* 17 | 18 | # now 19 | .now -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at spences10apps@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Scott Spence 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Localhost 2 | 3 | Modern web development guides hints and tips. 4 | 5 | ## Follow the guides 6 | 7 | 📺 [YouTube playlist] 8 | 9 | 📖 [The Post] 10 | 11 | 12 | 13 | [youtube playlist]: 14 | https://www.youtube.com/playlist?list=PLGi_uHe_v04DRZ58L_0O5cilalymkC7On 15 | [the post]: https://thelocalhost.io/2019/10/31/build-an-mdx-blog/ 16 | -------------------------------------------------------------------------------- /gatsby-browser.js: -------------------------------------------------------------------------------- 1 | import { wrapPageElement as wrap } from './root-wrapper' 2 | 3 | export const wrapPageElement = wrap 4 | -------------------------------------------------------------------------------- /gatsby-config.js: -------------------------------------------------------------------------------- 1 | const activeEnv = 2 | process.env.ACTIVE_ENV || process.env.NODE_ENV || 'development' 3 | 4 | console.log(`Using environment config: '${activeEnv}'`) 5 | 6 | require('dotenv').config({ 7 | path: `.env.${activeEnv}`, 8 | }) 9 | 10 | const siteMetadata = { 11 | title: `The Localhost`, 12 | description: `Modern web development guides hints and tips.`, 13 | image: `/default-site-image.jpg`, 14 | siteUrl: `https://thelocalhost.io`, 15 | siteLanguage: `en-GB`, 16 | siteLocale: `en_gb`, 17 | twitterUsername: `@spences10`, 18 | authorName: `Scott Spence`, 19 | favicon: `./static/favicon.png`, 20 | backgroundColor: `#f7f0eb`, 21 | themeColor: `#a2466c`, 22 | } 23 | 24 | module.exports = { 25 | siteMetadata: siteMetadata, 26 | plugins: [ 27 | `gatsby-transformer-sharp`, 28 | `gatsby-plugin-sharp`, 29 | `gatsby-plugin-react-helmet`, 30 | `gatsby-plugin-styled-components`, 31 | `gatsby-plugin-robots-txt`, 32 | `gatsby-plugin-sitemap`, 33 | `@pauliescanlon/gatsby-mdx-embed`, 34 | { 35 | resolve: `gatsby-plugin-mdx`, 36 | options: { 37 | extensions: [`.mdx`, `.md`], 38 | gatsbyRemarkPlugins: [ 39 | `gatsby-remark-copy-linked-files`, 40 | `gatsby-remark-smartypants`, 41 | `gatsby-remark-autolink-headers`, 42 | { 43 | resolve: `gatsby-remark-images`, 44 | options: { 45 | maxWidth: 640, 46 | withWebp: true, 47 | tracedSVG: true, 48 | }, 49 | }, 50 | { 51 | resolve: `gatsby-remark-external-links`, 52 | options: { 53 | target: `_blank`, 54 | rel: `noopener`, 55 | }, 56 | }, 57 | ], 58 | }, 59 | plugin: [ 60 | { 61 | resolve: `gatsby-remark-images`, 62 | options: { 63 | maxWidth: 680, 64 | }, 65 | }, 66 | ], 67 | }, 68 | { 69 | resolve: `gatsby-source-filesystem`, 70 | options: { 71 | path: `${__dirname}/posts`, 72 | name: `posts`, 73 | }, 74 | }, 75 | { 76 | resolve: `gatsby-plugin-google-fonts`, 77 | options: { 78 | fonts: [ 79 | `poppins\:400,500,600,700`, 80 | `pridi\:400,700`, 81 | `space mono\:400,700`, 82 | ], 83 | display: 'swap', 84 | }, 85 | }, 86 | { 87 | resolve: `gatsby-plugin-manifest`, 88 | options: { 89 | name: `The Localhost`, 90 | short_name: `Localhost`, 91 | start_url: `/`, 92 | background_color: siteMetadata.backgroundColor, 93 | theme_color: siteMetadata.themeColor, 94 | display: `standalone`, 95 | icon: siteMetadata.favicon, 96 | }, 97 | }, 98 | { 99 | resolve: `gatsby-plugin-zeit-now`, 100 | options: { 101 | globalHeaders: { 102 | 'referrer-policy': 'same-origin', 103 | 'feature-policy': 104 | "geolocation 'self'; microphone 'self'; camera 'self'", 105 | 'expect-ct': 'max-age=604800, enforce', 106 | 'strict-transport-security': 107 | 'max-age=31536000; includeSubDomains', 108 | 'x-frame-options': 'DENY', 109 | 'x-xss-protection': '1; mode=block', 110 | 'x-content-type-options': 'nosniff', 111 | 'x-download-options': 'noopen', 112 | }, 113 | }, 114 | }, 115 | { 116 | resolve: `gatsby-plugin-feed`, 117 | options: { 118 | query: ` 119 | { 120 | site { 121 | siteMetadata { 122 | title 123 | description 124 | siteUrl 125 | } 126 | } 127 | } 128 | `, 129 | feeds: [ 130 | { 131 | serialize: ({ query: { site, allMdx } }) => { 132 | return allMdx.nodes.map(node => { 133 | return Object.assign({}, node.frontmatter, { 134 | description: node.excerpt, 135 | date: node.frontmatter.date, 136 | url: site.siteMetadata.siteUrl + node.fields.slug, 137 | guid: site.siteMetadata.siteUrl + node.fields.slug, 138 | }) 139 | }) 140 | }, 141 | query: ` 142 | { 143 | allMdx( 144 | limit: 1000, 145 | sort: { order: DESC, fields: [frontmatter___date] }, 146 | filter: {frontmatter: {private: {eq:false}}} 147 | ) { 148 | nodes { 149 | id 150 | rawBody 151 | fields { 152 | slug 153 | } 154 | frontmatter { 155 | title 156 | date 157 | } 158 | } 159 | } 160 | } 161 | `, 162 | output: '/rss.xml', 163 | title: `${siteMetadata.title} Feed`, 164 | }, 165 | ], 166 | }, 167 | }, 168 | { 169 | resolve: `gatsby-plugin-offline`, 170 | options: { 171 | precachePages: [`/2019/*`, `/2020/*`], 172 | }, 173 | }, 174 | ], 175 | } 176 | -------------------------------------------------------------------------------- /gatsby-node.js: -------------------------------------------------------------------------------- 1 | const { createFilePath } = require(`gatsby-source-filesystem`) 2 | const path = require(`path`) 3 | 4 | exports.createPages = ({ actions, graphql }) => { 5 | const { createPage } = actions 6 | const postTemplate = path.resolve('src/templates/post-template.js') 7 | 8 | return graphql(` 9 | { 10 | allMdx(sort: { fields: [frontmatter___date], order: DESC }) { 11 | nodes { 12 | id 13 | excerpt(pruneLength: 250) 14 | frontmatter { 15 | title 16 | date 17 | } 18 | fields { 19 | slug 20 | } 21 | } 22 | } 23 | } 24 | `).then(result => { 25 | if (result.errors) { 26 | throw result.errors 27 | } 28 | 29 | const posts = result.data.allMdx.nodes 30 | 31 | posts.forEach((post, index) => { 32 | const previous = 33 | index === post.length - 1 ? null : posts[index + 1] 34 | const next = index === 0 ? null : posts[index - 1] 35 | 36 | createPage({ 37 | path: post.fields.slug, 38 | component: postTemplate, 39 | context: { 40 | slug: post.fields.slug, 41 | previous, 42 | next, 43 | }, 44 | }) 45 | }) 46 | }) 47 | } 48 | 49 | exports.onCreateNode = ({ node, actions, getNode }) => { 50 | const { createNodeField } = actions 51 | if (node.internal.type === `Mdx`) { 52 | const value = createFilePath({ node, getNode }) 53 | createNodeField({ 54 | name: `slug`, 55 | node, 56 | value, 57 | }) 58 | 59 | createNodeField({ 60 | name: `editLink`, 61 | node, 62 | value: `https://github.com/spences10/thelocalhost/edit/authoring${node.fileAbsolutePath.replace( 63 | __dirname, 64 | '' 65 | )}`, 66 | }) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /gatsby-ssr.js: -------------------------------------------------------------------------------- 1 | import { wrapPageElement as wrap } from './root-wrapper' 2 | 3 | export const wrapPageElement = wrap 4 | -------------------------------------------------------------------------------- /now.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "build": { 4 | "env": { 5 | "GATSBY_FATHOM_TRACKING_ID_THE_LOCALHOST": "@gatsby_fathom_tracking_id_the_localhost", 6 | "GATSBY_FATHOM_TRACKING_URL_THE_LOCALHOST": "@gatsby_fathom_tracking_url_the_localhost" 7 | } 8 | }, 9 | "trailingSlash": false 10 | } 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "thelocalhost", 3 | "version": "0.1.97", 4 | "description": "Modern web development guides hints and tips.", 5 | "main": "index.js", 6 | "keywords": [ 7 | "localhost", 8 | "dev-tips" 9 | ], 10 | "author": "Scott Spence ", 11 | "license": "MIT", 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/spences10/thelocalhost.git" 15 | }, 16 | "bugs": { 17 | "url": "https://github.com/spences10/thelocalhost/issues" 18 | }, 19 | "homepage": "https://github.com/spences10/thelocalhost#readme", 20 | "scripts": { 21 | "dev": "gatsby develop -p 9988 -o", 22 | "build": "gatsby build", 23 | "serve": "gatsby serve -p 9500 -o", 24 | "format": "pretty-quick", 25 | "postinstall": "patch-package" 26 | }, 27 | "husky": { 28 | "hooks": { 29 | "pre-commit": "pretty-quick --staged" 30 | } 31 | }, 32 | "prettier": { 33 | "singleQuote": true, 34 | "semi": false, 35 | "trailingComma": "es5", 36 | "printWidth": 70, 37 | "arrowParens": "avoid", 38 | "proseWrap": "always" 39 | }, 40 | "dependencies": { 41 | "@mdx-js/mdx": "1.6.1", 42 | "@mdx-js/react": "1.6.1", 43 | "@pauliescanlon/gatsby-mdx-embed": "0.0.19", 44 | "babel-plugin-styled-components": "1.10.7", 45 | "gatsby": "2.21.19", 46 | "gatsby-image": "2.4.3", 47 | "gatsby-plugin-feed": "2.5.1", 48 | "gatsby-plugin-google-fonts": "1.0.1", 49 | "gatsby-plugin-manifest": "2.4.2", 50 | "gatsby-plugin-mdx": "1.2.6", 51 | "gatsby-plugin-offline": "3.2.1", 52 | "gatsby-plugin-react-helmet": "3.3.1", 53 | "gatsby-plugin-robots-txt": "1.5.0", 54 | "gatsby-plugin-sharp": "2.6.2", 55 | "gatsby-plugin-sitemap": "2.4.2", 56 | "gatsby-plugin-styled-components": "3.3.1", 57 | "gatsby-plugin-zeit-now": "0.3.0", 58 | "gatsby-remark-autolink-headers": "2.3.1", 59 | "gatsby-remark-copy-linked-files": "2.3.2", 60 | "gatsby-remark-external-links": "0.0.4", 61 | "gatsby-remark-images": "3.3.1", 62 | "gatsby-remark-smartypants": "2.3.1", 63 | "gatsby-source-filesystem": "2.3.1", 64 | "gatsby-transformer-sharp": "2.5.2", 65 | "prism-react-renderer": "1.1.0", 66 | "react": "16.13.1", 67 | "react-device-detect": "1.12.1", 68 | "react-dom": "16.13.1", 69 | "react-helmet": "6.0.0", 70 | "react-live": "2.2.2", 71 | "react-seo-component": "2.0.0", 72 | "react-share": "4.1.0", 73 | "react-tooltip": "4.2.6", 74 | "styled-breakpoints": "8.1.0", 75 | "styled-components": "5.1.0", 76 | "styled-reset": "4.1.4", 77 | "victormono": "1.3.1" 78 | }, 79 | "devDependencies": { 80 | "husky": "4.2.5", 81 | "patch-package": "6.2.2", 82 | "postinstall-postinstall": "2.1.0", 83 | "prettier": "2.0.5", 84 | "pretty-quick": "2.0.1" 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /patches/victormono+1.3.1.patch: -------------------------------------------------------------------------------- 1 | diff --git a/node_modules/victormono/dist/index.css b/node_modules/victormono/dist/index.css 2 | index 82c84f1..9e1131f 100644 3 | --- a/node_modules/victormono/dist/index.css 4 | +++ b/node_modules/victormono/dist/index.css 5 | @@ -4,6 +4,7 @@ 6 | url("woff/VictorMono-Regular.woff") format("woff"); 7 | font-weight: 400; 8 | font-style: normal; 9 | + font-display: swap; 10 | } 11 | 12 | @font-face { 13 | @@ -12,6 +13,7 @@ 14 | url("woff/VictorMono-Italic.woff") format("woff"); 15 | font-weight: 400; 16 | font-style: italic; 17 | + font-display: swap; 18 | } 19 | 20 | @font-face { 21 | @@ -20,6 +22,7 @@ 22 | url("woff/VictorMono-Bold.woff") format("woff"); 23 | font-weight: 700; 24 | font-style: normal; 25 | + font-display: swap; 26 | } 27 | 28 | @font-face { 29 | @@ -28,4 +31,5 @@ 30 | url("woff/VictorMono-BoldItalic.woff") format("woff"); 31 | font-weight: 700; 32 | font-style: italic; 33 | + font-display: swap; 34 | } 35 | \ No newline at end of file 36 | -------------------------------------------------------------------------------- /posts/2016/10/hello-world/24/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2016-10-24 3 | title: Hello World! 4 | tags: ['hello world', 'getting started'] 5 | private: false 6 | --- 7 | 8 | My first post using Gatsby, awesome static site generator 9 | [Gatsby][gatsby] from [Kyle Mathews][kyle] 10 | 11 | So not a lot to see, I'll just be configuring this and adding all my 12 | old blog posts. 13 | 14 | 15 | 16 | [gatsby]: https://github.com/gatsbyjs/gatsby 17 | [kyle]: https://github.com/KyleAMathews 18 | -------------------------------------------------------------------------------- /posts/2016/11/13/freecodecamp/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2016-11-13 3 | title: freeCodeCamp 4 | tags: ['freecodecamp', 'learning'] 5 | private: false 6 | --- 7 | 8 | Ok, I have recently discovered and started doing freeCodeCamp(🔥) 9 | which so far I'm really enjoying. 10 | 11 | Since being out of work I have had some time to start exploring 12 | different programming languages and technologies but I haven't found 13 | any courses that I have started and thought "you know what I'm going 14 | to stick this out" that's before I discovered FCC, FCC is very much a 15 | real world situation course where you go over some basics first then 16 | apply them, once you have learnt enough you then have to complete 17 | projects using the skills you have just learned. 18 | 19 | So far I have made a tribute page 20 | [DJ Hype](http://codepen.io/spences10/full/NbqZob/) and created a 21 | personal [Portfolio](http://codepen.io/spences10/full/NbGXoy/) page on 22 | [CODEPEN.io](http://codepen.io/spences10/) there's some great examples 23 | on [CODEPEN.io](http://codepen.io/) to help you get started and so far 24 | I have really enjoyed them. 25 | 26 | So now onto JavaScript! 27 | -------------------------------------------------------------------------------- /posts/2016/11/14/vba-ide-export/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2016-11-14 3 | title: VBA Code Export for Version Control Systems 4 | tags: ['information', 'vcs', 'vba'] 5 | private: false 6 | --- 7 | 8 | I have seen the same situation many times now in my career as a VBA 9 | Developer about how source code control is managed with VBA projects. 10 | 11 | Source control on VBA has long been a bit of a nonsense, there isn't 12 | any really. When I started my first developer role it was talked about 13 | in my team why we don't use it and the best efforts the team did at 14 | the time was save the new version to a different folder location and 15 | to compare changes in the code from a previous version meant getting a 16 | text compare app copy pasting the code into it from the two different 17 | versions so you could track what was changed. 18 | 19 | My colleague at the time and now very good friend 20 | [Paul Crook](https://uk.linkedin.com/in/paul-crook-4065a461) came up 21 | with the base of what I have done with the 22 | [VBA IDE Code Export tool](https://github.com/spences10/VBA-IDE-Code-Export) 23 | I have just extended some parts of his base that I feel were needed. 24 | 25 | What was lacking from Crookie's code, which I brought up at the time 26 | with him was that it only exported `*.bas`, `*.cls` and `*.frm` files 27 | I did ask about code contained within the `ThisWorkbook` and the 28 | `Sheet*` modules. What we decided to do was if there was code in those 29 | modules was to abstract it out into its own module, so `ThisWorkbook` 30 | would call out to `ThisWorkbook.bas` this was a bit of extra work to 31 | begin with but ultimately benefited us in the long run with good 32 | version control. 33 | 34 | I wasn't keen on how you had to work with this so decided to have a 35 | play around with it when I put it on 36 | [GitHub](https://github.com/spences10/VBA-IDE-Code-Export) I decided 37 | to try right some of that, I think I may have made some things worse 38 | but I'm keen to make another revision of the tool in the future to 39 | correct that. 40 | 41 | ### what did you make better 42 | 43 | - added functionality to save code from `ThisWorkbook` and `Sheet*` 44 | - made a `.conf` file to save the project contents to meaning there 45 | were no modules left in the project after export 46 | - added the ability to specify an import and export location, it was 47 | defaulted to the root of where the source workbook was located 48 | 49 | ### what did you mess up 50 | 51 | - added a form, means more validation 52 | - added ranges to the configuration worksheet for storing locations 53 | other than the `ThisWorkbook` file location 54 | - didn't add the new functionality to the existing code 55 | 56 | ### up next 57 | 58 | - possibly remove the old method that copied out the project contents 59 | to a module and go full retard with the `.conf` file 60 | -------------------------------------------------------------------------------- /posts/2016/12/03/first-vscode-extension/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2016-12-03 3 | title: My first Microsoft Visual Studio Code [VSCode] extension 4 | tags: ['information', 'vscode', 'extension'] 5 | private: false 6 | --- 7 | 8 | I'm a published developer! [sort of] Well that was a bit painful, well 9 | not actually I mean from the documentation I feel I was a bit mislead. 10 | 11 | ![market-place-image](./visual-studio-marketplace.png) 12 | 13 | So for those of you that know what I do for a living I'm primarily an 14 | Analyst Developer with a skill set of VBA and SQL which has put me in 15 | good stead for the last 10+ years. I'm currently 'up-skilling' myself 16 | on more general programming languages, but enough of that! I basically 17 | wanted to use [VSCode][vscode] with VBA which is fine as it's just 18 | text files but I wanted some of the shexy stuff that VSCode comes 19 | with. 20 | 21 | I'm not going to go into how awesome (I think) VSCode is here but I 22 | will mention that for the purpose of me wanting to use (or at least 23 | see syntax highlighting) I found this extension for 24 | [VBScript][vbscript] which was neat but didn't give me any 25 | intellisense for even the most straight forward stuff like to create a 26 | `Sub` or `Function`. 27 | 28 | So that got me playing around with making my own [snippets][snippets] 29 | and I found that after a while I had quite a lot of them so I decided 30 | to put them on the VSCode market place. 31 | 32 | So, what I found is that Microsoft really want you to make VSCode 33 | extensions and give you all the tools you need to do so. 34 | 35 | I found guides [here][guide1], [here][guide2] and [here][guide3] all 36 | of which have you using [Yeoman](http://yeoman.io/) by installing via 37 | npm, now I've never heard of Yeoman before trying to do this so I 38 | don't have an opinion on that apart from to say it was a bit of a 39 | ballache to get any of it up and running. I tried installing it on 40 | both my home machine and a Cloud9 machine several times over with no 41 | success. 42 | 43 | ![YeomanErr](./yeoman-err.png) 44 | 45 | Got tired after uninstalling and reinstalling several times at home 46 | and on the cloud so moved on. I read 47 | [this](https://code.visualstudio.com/docs/tools/vscecli) guide about 48 | setting yourself up as a publisher on the Microsoft VSCode 49 | [Marketplace](https://marketplace.visualstudio.com/) using with `vsce` 50 | (agin installed with npm) so after creating a Personal Access Token 51 | and creating my publisher account I could then publish my extension. 52 | But this was the thing my extension is just the `vbscrip.json` file on 53 | my hard drive. 54 | 55 | ## How do I make it into a extension? 56 | 57 | After reading up on extension I thought that you needed to have your 58 | package 'packaged' with a `.vsix` extension so looking at the links 59 | earlier you need to install Yeoman (bugger!) 60 | 61 | I looked around at other snippets packages on GitHub and couldn't 62 | understand why I needed to have my snippets packaged up in this 63 | `.vsix` file, all it was, was the `.json` file from my computer. 64 | 65 | So this is what I did, I copied the file structure from one of another 66 | GitHub repositories that were just snippets, it basically consisted of 67 | two folders and a `package.json` file. I replaced all the relevant 68 | properties in the `.json` file and created a 69 | [GitHub](https://github.com/spences10/vba-snippets) repository just 70 | for the sake of having all my lovingly crafted snippets kept safe. 71 | 72 | So it looked like I had no way to get this onto the Marketplace, I was 73 | pretty bummed but thought I'd just go though the process of publishing 74 | an extension with `vsce` by cd'ing to the folder the package was in 75 | and going through the commands so I tried `vsce publish 1.0.0` 76 | 77 | I was pretty surprised (and relieved) to see the output pictured. 78 | 79 | ![vscePublish](./vsce-publish.png) 80 | 81 | I had a quick check of my publisher profile and lo and behold, there's 82 | my extension! 83 | 84 | ![YeomanErr](./marketplace-extensions-management.png) 85 | 86 | Here's my extension: 87 | [VBA Snippets](https://marketplace.visualstudio.com/items?itemName=spences10.vba-snippets) 88 | from there you can fin the 89 | [GitHub](https://github.com/spences10/vba-snippets) repository too, I 90 | hope it comes in handy for you one day! 91 | 92 | 93 | 94 | [vbscript]: 95 | https://marketplace.visualstudio.com/items?itemName=luggage66.VBScript 96 | [vscode]: https://code.visualstudio.com/ 97 | [snippets]: 98 | https://code.visualstudio.com/Docs/customization/userdefinedsnippets 99 | [guide1]: https://code.visualstudio.com/docs/extensions/overview 100 | [guide2]: 101 | https://code.visualstudio.com/docs/extensions/example-hello-world 102 | [guide3]: 103 | https://code.visualstudio.com/docs/extensions/testing-extensions 104 | 105 | 106 | -------------------------------------------------------------------------------- /posts/2016/12/03/first-vscode-extension/marketplace-extensions-management.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2016/12/03/first-vscode-extension/marketplace-extensions-management.png -------------------------------------------------------------------------------- /posts/2016/12/03/first-vscode-extension/visual-studio-marketplace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2016/12/03/first-vscode-extension/visual-studio-marketplace.png -------------------------------------------------------------------------------- /posts/2016/12/03/first-vscode-extension/vsce-publish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2016/12/03/first-vscode-extension/vsce-publish.png -------------------------------------------------------------------------------- /posts/2016/12/03/first-vscode-extension/yeoman-err.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2016/12/03/first-vscode-extension/yeoman-err.png -------------------------------------------------------------------------------- /posts/2016/12/05/job-hunting/shady-recruiter-middle-man.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2016/12/05/job-hunting/shady-recruiter-middle-man.jpg -------------------------------------------------------------------------------- /posts/2016/12/05/job-hunting/stress-office.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2016/12/05/job-hunting/stress-office.jpg -------------------------------------------------------------------------------- /posts/2016/12/17/starting-again-with-jekyll/base-jekyll-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2016/12/17/starting-again-with-jekyll/base-jekyll-project.png -------------------------------------------------------------------------------- /posts/2016/12/17/starting-again-with-jekyll/base-jekyll-site.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2016/12/17/starting-again-with-jekyll/base-jekyll-site.png -------------------------------------------------------------------------------- /posts/2016/12/17/starting-again-with-jekyll/dem-commits.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2016/12/17/starting-again-with-jekyll/dem-commits.png -------------------------------------------------------------------------------- /posts/2016/12/17/starting-again-with-jekyll/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2016-12-17 3 | title: Starting again with Jekyll 4 | tags: ['ramble'] 5 | private: false 6 | --- 7 | 8 | Since setting up this blog I haven't really bothered with Jekyll any 9 | more than just forking Barry Clarke's repo of Jekyll Now and adding 10 | these posts as and when the feeling takes me. 11 | 12 | ![jekyll logo](./jekyll-logo.png) 13 | 14 | So I got to checking out Barry's blog and his Jekyll Now templates and 15 | tried to make sense of the two so I could make my own, based off of 16 | the ideas I got from Barry's blog. 17 | 18 | ## Development environment, enter Cloud 9 19 | 20 | I tried to set up Ruby on my Windows machine and it didn't go well, 21 | then I tried to set it up on my Raspberry Pi, that didn't go well 22 | either. Then I recalled that I could have any number of different 23 | environments with [Cloud9](https://c9.io/?redirect=0) so I set up a 24 | Ruby machine on there and installed Jekyll, no problem 25 | 26 | ### Setup 27 | 28 | It wasn't as simple as just going to the local host page as it's a 29 | cloud based system so after som digging I found this from 30 | Jean-François L'Heureux [jflheureux](https://github.com/jflheureux) on 31 | GitHub. 32 | 33 | [https://www.jflh.ca/2016-01-18-running-jekyll-on-cloud9](https://www.jflh.ca/2016-01-18-running-jekyll-on-cloud9) 34 | 35 | Basically you need to set up a Run Configuration on your c9 box, 36 | thanks for that Jean-François. 37 | 38 | ## CSS 39 | 40 | For some reason I thought that a Jekyll page didn't use CSS, well the 41 | reason may have been that there was nothing like that in the 'vanilla' 42 | Jekyll site when you run the `jekyll new myblog` you get very little 43 | in the was of bells and whistles. 44 | 45 | #### here is the base project 46 | 47 | ![bas-project-layout](./base-jekyll-project.png) 48 | 49 | Running the following from the terminal on my Ruby development box 50 | 51 | ``` 52 | ~ $ gem install jekyll bundler 53 | ~ $ jekyll new myblog 54 | ~ $ cd myblog 55 | ``` 56 | 57 | Omitting the `~/myblog $ bundle exec jekyll serve` and 58 | `# => Now browse to http://localhost:4000` for reasons just mentioned. 59 | 60 | Use the run configuration 61 | `jekyll serve --host $IP --port $PORT --config _config.yml,_local_config.yml` 62 | 63 | You get this: 64 | 65 | #### new blog yay! 66 | 67 | ![base-jekyll-site](./base-jekyll-site.png) 68 | 69 | ## Confusing 70 | 71 | Jekyll uses Liquid templating language which, for someone like me was 72 | a bit confusing. With me just getting used to the layout of a 73 | 'standard' web page I was then presented with liquid 'tags' something 74 | I'm still not completely clear on what some of them do. 75 | 76 | `_layouts, _includes, meta.html` 77 | 78 | WTF? I had no idea, I'm still not totally clear on the why, I add a 79 | default.html then Jekyll complains that there's a missing meta.html 80 | file, I create a \_includes folder and add an empty meta.html and it 81 | builds fine, no idea. 82 | 83 | So after creating a `default.html` and then comparing with Jekyll Now 84 | and Barry's sites I was able to piece together a `default.html`, 85 | `page.html` and `post.html` which looked hideous so I then had to 86 | start with CSS on the page,I took the majority of it from Barry's blog 87 | page with the intention of modifying it to my own liking. 88 | 89 | In the end I took quite a bit of CSS, the 90 | [Meyer Reset](http://meyerweb.com/eric/tools/css/reset/) was something 91 | I knew nothing of before starting this, now I think it's quite a handy 92 | thing to have/know. 93 | 94 | Variables, again I knew nothing about this before playing around with 95 | Jekyll but really helped me understand CSS a little bit more than I 96 | did before. 97 | 98 | Then stuff for analytics and Disqus, then there was stuff I added in 99 | that I liked, like font-awesome and some Google fonts I like so I 100 | could have a nice footer like the one in my CodePen portfolio I like. 101 | 102 | ## Markdown 103 | 104 | Oh, it's not the right Markdown, why isn't is showing the GitHub 105 | Markdown Scott?? Because you've used the `@import "highlights";` on 106 | your `style.css` oh ok, so I'd prefer GitHub Markdown, ok no problem, 107 | go remove the `@import "highlights";` from your `style.css` you'll be 108 | golden, no worries. Queue a raft of commits with me dicking around 109 | with various combinations of having corrected `_config.yml` entries it 110 | got pretty messy. 111 | 112 | ![dem-commits](./dem-commits.png) 113 | 114 | Currently I am still with the `_hilights.scss` in the `sass` folder 115 | which I'm going to have to play around with to get it how I like it, 116 | hopefully I'll get to learn a bit more about it all and understand how 117 | much of a tool I was. 118 | 119 | ## Preview 120 | 121 | One last thing that bugged me that I couldn't do was the content 122 | preview thing on the posts, it's partly why I went from Jekyll Now to 123 | my own vanilla build, I was getting that first paragraph to show on 124 | the main blog page I found it eventually, not on the `post.html` or 125 | the `default.html` no it was on the `index.html` here: 126 | 127 | ` {``{ post.content | split:"" | first }``} ` 128 | 129 | Then add the `` tag after the first paragraph on your post, 130 | then I added a class to float the image on the top of the post and 131 | flow around the image, the CSS is this: 132 | 133 | ``` 134 | // see image in content preview 135 | // only adjust width OR height so aspect ration is maintained 136 | .floated{ 137 | float: right; 138 | display: block; 139 | width: 33vw; 140 | max-width: 250px; 141 | } 142 | ``` 143 | 144 | So I have the basics I think, still a fair bit to play around with but 145 | for now I have what I need. 146 | -------------------------------------------------------------------------------- /posts/2016/12/17/starting-again-with-jekyll/jekyll-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2016/12/17/starting-again-with-jekyll/jekyll-logo.png -------------------------------------------------------------------------------- /posts/2017/01/05/git-and-github/fork-a-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2017/01/05/git-and-github/fork-a-repo.png -------------------------------------------------------------------------------- /posts/2017/01/05/git-and-github/git-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2017/01/05/git-and-github/git-logo.jpg -------------------------------------------------------------------------------- /posts/2017/01/05/git-and-github/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2017-01-05 3 | title: Git and GitHub 4 | tags: ['information', 'guide'] 5 | private: false 6 | --- 7 | 8 | I know why Linus called it that now! 9 | 10 | If you're reading this there's a good chance you know at least the 11 | basics of Git but if like me and you are the only person making 12 | changes to your repos then there's a good chance that you just use 13 | `git push origin master` to move your changes from your local machine 14 | to GitHub, this is not best practice. 15 | 16 | ![image of octocat](./git-logo.jpg) 17 | 18 | What if it's not your repository you want to make changes to? You'll 19 | need to create a pull request, where you make a copy (fork) of the 20 | repo, make the changes to your copy (fork) then request that the owner 21 | of the original repo pulls your changes into their repo. All super 22 | straight forward, right? 23 | 24 | As an example I'm going to document my change to the 25 | [awesome-twitter-bots](https://github.com/spences10/awesome-twitter-bots) 26 | repo that [@amanhimself](https://twitter.com/amanhimself) asked me to 27 | contribute to after I made a Twitter bot with his guides. 28 | 29 | ## Step 1 30 | 31 | I will need to fork the repository on GitHub so I can make my changes. 32 | 33 | ![fork-a-repo](./fork-a-repo.png) 34 | 35 | Then clone my forked repository to where I'm all going to make the 36 | changes on my computer: 37 | 38 | ``` 39 | $ git clone https://github.com/spences10/awesome-twitter-bots 40 | ``` 41 | 42 | Connect the fork to the Original Repository: 43 | 44 | ``` 45 | $ git remote add upstream https://github.com/amandeepmittal/awesome-twitter-bots 46 | ``` 47 | 48 | ## Step 2: 49 | 50 | Use `git status` to check what branch you are currently on. 51 | 52 | Make a (my) branch: 53 | 54 | I'm adding the 55 | [Twitter bot](https://spences10.github.io/2017/01/04/twitter-mctwitbot.html) 56 | I made so I'm going to give my branch the same name as my repo 57 | 58 | ``` 59 | $ git branch spences10-twitter-bot 60 | ``` 61 | 62 | Now change to that branch with: 63 | 64 | ``` 65 | $ git checkout spences10-twitter-bot 66 | ``` 67 | 68 | It should say you have switched to the branch but you can check with 69 | `git status` 70 | 71 | Add your files **_note_** if you are adding a folder (like I am) just 72 | using `git add .` will add the folder as a file (which I learned from 73 | bitter experience), what you will need to do is: 74 | 75 | ``` 76 | $ git add spences10-twitter-bot/\\* 77 | ``` 78 | 79 | This will add the folder and all its contents, I would post my 80 | terminal 'output of shame' here as it would take up the whole screen. 81 | So now I have added the folder I need to commit to my local repo with: 82 | 83 | ``` 84 | $ git commit -m 'initial commit' 85 | ``` 86 | 87 | I get the terminal output confirming my files are added, then I 88 | `git push` to my branch I checked out earlier: 89 | 90 | ``` 91 | $ git push origin spences10-twitter-bot 92 | ``` 93 | 94 | A quick check of the repo on GitHub confirms that the files are there 95 | I'm now ready to add a contributor 96 | [@amandeepmittal](https://github.com/amandeepmittal) via the 97 | [/settings/collaboration](https://github.com/spences10/awesome-twitter-bots/settings/collaboration) 98 | section of my repo. I can then copy the invite link and send to Aman, 99 | I'm sure he'll be thrilled to see it! 100 | 101 | ## Step 3 102 | 103 | Visit Aman's repo and GitHub will have detected that I have pushed a 104 | branch to a fork, from here I can click on the 'Compare & pull 105 | request' button. 106 | 107 | In the 'Open a pull request' page I'll need to select the my fork and 108 | then my branch, so `spences10\awesome-twitter-bots` and my branch 109 | which is `spences10-twitter-bot` click the 'Create pull request' 110 | button. 111 | 112 | ![open-a-pull-request](./open-a-pull-request.png) 113 | 114 | The rest is up to the repository owner (Aman) now where he can chose 115 | to merge my changes into his repo. 116 | 117 | --- 118 | 119 | ### That's not the end though 120 | 121 | It turned out that Aman just wanted me to update the 122 | [README.md](https://github.com/amandeepmittal/awesome-twitter-bots/blob/master/README.md) 123 | on the repo so my pull request was cancelled :flushed: 124 | 125 | This was good though because I had the opportunity to go through the 126 | whole thing again, thus getting more familiar with the process, after 127 | making my changes to my fork it was another pull request [PR] which 128 | was then successfully merged as PR 129 | [#2](https://github.com/amandeepmittal/awesome-twitter-bots/pull/2) 130 | 131 | ### Resources 132 | 133 | A great resource for me was 134 | [Git-It](http://jlord.us/git-it/index.html) 135 | 136 | And obviously the [GitHub Help](https://help.github.com/) 137 | documentation. 138 | 139 | ### 2fa 140 | 141 | Another thing to note is if you're using two factor authentication 142 | you'll need to add your auth token in as a `remote set-url` so you can 143 | push/pull without having to authenticate each time. 144 | 145 | `git remote set-url origin https://yourgithubuser:your-token@github.com/yourgithubuser/yourrepo.git` 146 | -------------------------------------------------------------------------------- /posts/2017/01/05/git-and-github/open-a-pull-request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2017/01/05/git-and-github/open-a-pull-request.png -------------------------------------------------------------------------------- /posts/2017/03/15/code-life-balance/fccbreakdown.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2017/03/15/code-life-balance/fccbreakdown.jpg -------------------------------------------------------------------------------- /posts/2017/03/15/code-life-balance/gollum.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2017/03/15/code-life-balance/gollum.jpg -------------------------------------------------------------------------------- /posts/2017/03/15/code-life-balance/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2017-03-15 3 | title: Code life balance 4 | tags: ['career', 'ramble'] 5 | private: false 6 | --- 7 | 8 | Just some rationalisation of what I'm currently doing. 9 | 10 | Recently I have decided that I'm going to improve my current skill 11 | set. To do this I'm studying with freeCodeCamp for a full stack 12 | developer certification, I'm also trying to learn as much as I can 13 | about the languages that come with that HTML, CSS and JavaScript as 14 | well as getting familiar with everything else in between like Git and 15 | GitHub, development environments like Cloud9 and services like Digital 16 | Ocean and AWS. 17 | 18 | To do all of this I need time and being married with a young family 19 | and having a full time job my time is at a premium. 20 | 21 | The freeCodeCamp curriculum is 2,080 hours, so let's break that down 22 | quickly. 23 | 24 | Like I said with a full time job and a family spare time is precious, 25 | I have taken to getting up most mornings around an hour earlier than 26 | usual @~05:30 that gave me around 1.5 hours before having to get ready 27 | for the day taking kids to school and the daily commute. In the 28 | evenings I usually have from 20:00–22:00 but this is full of 29 | interruptions so you could probably condense it down to about 1.5 30 | hours again. 31 | 32 | ![](./gollum.jpg) 33 | 34 | So. 35 | 36 | Let say I'm lazer focussed and relentlessly do 1 hour in the morning 37 | and 3 hours in the evening 4 hours a day 2,080/4 so 520 days? That's 38 | 1.4 years, wow! Ok now let's be a bit more realistic, 1 hour in the 39 | morning 1 hour in the evening, 1040 = 2.85 nearly 3 years, oh! 40 | 41 | Ok, so what if I was a full time student? 8 hours a day 1,080/8=135 42 | three months! How much do I want this then? 43 | 44 | Currently I'm managing 45min-1hour in the AM then 1hr-2hrs in the PM 45 | so at very best I could manage to finish the curriculum in a year, 46 | that's if I finish the curriculum at all, I read loads of posts about 47 | how people have managed to get full time developer jobs after only 48 | doing half of the freeCodeCamp curriculum this doesn't help. It's 49 | great to see success stories and inspiring to read but a lot of the 50 | time this adds unnecessary pressure on yourself. 51 | 52 | My family are great and understand the situation but your 53 | relationships are priority and they can get a bit strained when all 54 | you're doing is staring at a monitor whenever you get a spare 45 55 | minutes. 56 | 57 | ![](./fccbreakdown.jpg) 58 | 59 | [#100DaysOfCode] has been a great tool for me with regard to building 60 | good habits and something that has both distracted me from purely 61 | concentrating on my freeCodeCamp and also accelerated my GitHub open 62 | source interactions. Since starting the challenge I have contributed 63 | to several GitHub projects and made some of my own. 64 | 65 | I have also created a personal goals repo like the one Una Kravets has 66 | on her GitHub this will be what I’ll use going forward after I have 67 | completed the 100 Days of Code challenge, I’m not going to take part 68 | in the 301 days of code challenge as I’d like to go on holiday without 69 | having to think about any coding for a week or so. 70 | 71 | I often think if I am a proper developer and what am I doing all this 72 | for, then I take this handy little quiz: 73 | 74 | http://amiarealdeveloper.com/ 75 | 76 | We shall see where I am in a years time 👍 77 | 78 | [100daysofcode]: 79 | https://medium.freecodecamp.com/start-2017-with-the-100daysofcode-improved-and-updated-18ce604b237b 80 | -------------------------------------------------------------------------------- /posts/2017/05/31/gets-better-with-git/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2017-05-31 3 | title: Just starting out with Git and GitHub? It gets easier, honest! 4 | tags: ['information', 'guide'] 5 | private: false 6 | --- 7 | 8 | No doubt you have heard of Git or GitHub for source control, but 9 | **what is source control?** 10 | 11 | > “Revision control (also known as version control, source control or 12 | > (source) code management (SCM)) is the management of multiple 13 | > revisions of the same unit of information.” 14 | 15 | Cool story br0! In other words: Source control allows distributed work 16 | in teams of any size, at different locations, while avoiding conflicts 17 | in source code changes. 18 | 19 | Really!? Thanks for clearing that up! 20 | 21 | Lets look at it this way… 22 | 23 | > In its simplest term it's like a “Save As”. You want the new file 24 | > without getting rid of the changes on the old one. It's an everyday 25 | > situation, except on a software project there is the potential for a 26 | > lot of changes. 27 | 28 | https://twitter.com/lindakatcodes/status/869086021220261888 29 | 30 | A familiar sentiment for anyone starting out with Git 31 | 32 | ## Concepts 33 | 34 | There are some basic concepts about version control I'll quickly go 35 | over here, these terms used in many SCM systems some relevant to Git 36 | and GitHub some to other systems. 37 | 38 | **Repository/repo:** The database storing the files. 39 | 40 | **Branch:** Create a separate copy of a repo for use on your computer. 41 | 42 | **Revert/rollback:** Go back to a previously saved version of the 43 | codebase/repo. 44 | 45 | **Push:** Push is an access level on the repo, if you have no push 46 | access you will need to make a pull request. 47 | 48 | **Pull:** If you have no Push access you can make a pull request which 49 | will notify the repo owner you want to merge your changes into their 50 | code. 51 | 52 | If you are just starting out then your most used commands will 53 | probably be : 54 | 55 | ```bash 56 | git add . 57 | git commit -m 'some informative message' 58 | git push origin master 59 | ``` 60 | 61 | Those commands have served me well in my early days of learning how to 62 | get my code back up to GitHub. 63 | 64 | `video: https://www.youtube.com/watch?v=CDeG4S-mJts` 65 | 66 | > **Git and GitHub** Git and GitHub are two separate things, Git is a 67 | > free and open source version control system whilst GitHub uses Git 68 | > technology to host your repositories on the GitHub.com servers. 69 | 70 | Git and GitHub were a bit confusing for me when I first started out 71 | with them, I was familiar with VCS before but that was in the shape of 72 | Microsoft's Visual SourceSafe and Team Foundation Server where you 73 | have a nice GUI to guide you through the check-in and check-out 74 | process, for those the process was: 75 | 76 | - **Check-out:** make a copy of the repository you wanted to make 77 | changes to on your machine, once you have made your change then, 78 | Check-in your changes. 79 | 80 | - **Check-in:** add your changes back to the repository with an 81 | accompanying message detailing the change you have made. 82 | 83 | With Git it's a bit less fancy, all via the command line, but pretty 84 | much the same as with VSS and TFS. 85 | 86 | - Clone the repository: Make a copy of the repo on your machine. 87 | - Make changes. 88 | - Once the changes are made then add them back with accompanying 89 | commit messages. 90 | - Push the changes back to the repo on Github. 91 | 92 | The documentation on GitHub is fantastic for anything you want to 93 | achieve and in this post I have referenced some the documentation. 94 | 95 | It can get a bit overwhelming though, especially if you get out of 96 | sync, i.e. forget to pull a change made on the remote then try to 97 | check your changes in before pulling the changes into your local 98 | version. I'm by no means confident if things go a bit wrong but I have 99 | developed a “[Commit Often Perfect Later]” approach so if you do break 100 | something you din't lose too much of you valuable time trying to work 101 | out what went wrong where. 102 | 103 | If you take a look at a repo you have cloned from GitHub you will see 104 | there is a file called `.git` this is like a little database of all 105 | the changes you have made on your machine and it contains all the 106 | information it needs to connect to GitHub and make the changes it 107 | needs to make to the master repo [or whatever branch you're pushing 108 | the changes to]. 109 | 110 | I made a cheat sheet [Gist] which I used every time I went near Git, 111 | it has now turned into a [repo] of other cheat sheets I still use on a 112 | daily basis. 113 | 114 | In it I cover these situations: 115 | 116 | - Make a new project on your machine that you want to add to GitHub? 117 | Look here. 118 | - Cloning a repo from someone else's GitHub and pushing it to a repo 119 | on my GitHub, or “I didn't make a fork, what do I do now!” 120 | - You have a fork which you need to update before making any changes. 121 | 122 | Workflow will be different for differing situations, for me as a noob 123 | developer I have tried to document anything I have come across with 124 | Git so I can reference back to it for that one time I need it but 125 | can't remember what I did at 21:45 on a Wednesday just to get the code 126 | checked into GitHub. 127 | 128 | There are many GUIs that integrate with Git for use with GitHub the 129 | official GitHub one is pretty nice but I quickly got into situations 130 | that the GUI couldn't get me out of so I have stuck with the terminal 131 | since, well there is VSCode though which has a beautiful Git UI that I 132 | use daily, but there are some things that I still use the terminal 133 | for: 134 | 135 | ```bash 136 | git status 137 | git checkout 138 | git [push] tags 139 | ``` 140 | 141 | All pretty handy, there is probably extensions out there to help with 142 | these but for now I'm pretty comfortable doing it via the command 143 | line. 144 | 145 | Any tips or tricks you use in Git you'd like to share? Please feel 146 | free to leave a comment or better still add to the repo via a pull 147 | request. 148 | 149 | If any of this has helped you in any way feel free to like the article 150 | and share it on social media. 151 | 152 | Many thanks. 153 | 154 | 155 | 156 | [commit often perfect later]: 157 | https://gist.github.com/SethRobertson/1540906/68feeabfe906ec1eb893e4fa45f402795ed6e62c#commit 158 | [gist]: 159 | https://gist.github.com/spences10/5c492e197e95158809a83650ff97fc3a#useful-git-commands 160 | [repo]: https://github.com/spences10/cheat-sheets 161 | -------------------------------------------------------------------------------- /posts/2017/06/01/beginner-to-git-aliases/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2017-06-01 3 | title: 4 | Moving from beginner to [slightly more] advanced git with aliases. 5 | tags: ['information', 'guide'] 6 | private: false 7 | --- 8 | 9 | Speed up your git workflow with git aliases, this is a brief 10 | introduction on using aliases 👌🚀👍 11 | 12 | The more you work with Git the more familiar you become with the 13 | commands used in your every day workflow for your projects or your 14 | team's projects. 15 | 16 | Commands like naming and creating feature branches making pull 17 | requests or pushing your changes if you have the requisite 18 | permissions. 19 | 20 | So still used by me on a daily basis, and everyone else that uses git 21 | [I presume] is the `git add .` command, then 22 | `git commit -m 'my awesome feature'` and `git push` or 23 | `git push origin ` 24 | 25 | In my short time using Git I have always just typed out the full 26 | commands [usually with [my cheatsheet][git-cheatsheet] close to hand] 27 | and thought nothing more of it, that is how you use the tool, right? 28 | 29 | Well that was what I foolishly presumed until I learned about 30 | dotfiles, I learned about `.` files from listening to the 31 | [toolsday.io][toolsday] podcast with [Chris][chris] and [Una][una] a 32 | great channel for learning about tooling 👍 the podcast was about [Git 33 | Tools][git-tools] give it a listen it's a great show. 34 | 35 | This was a pretty cool learning experience for me and I now have a 36 | pretty efficient git workflow 🚀 37 | 38 | Let's go over `.gitconfig`, do you remember having to enter your email 39 | address and name when first setting up Git on your computer? That 40 | information is stored in your `.gitconfig` file, your file will be 41 | located in your user folder on Windows 42 | `C:\Users\yourusername\.gitconfig` or `~/.gitconfig` on Linux/Mac 43 | 44 | If you navigate to the file in the text editor of your choice and pop 45 | it open you'll see your details under the `[user]` flag, here's mine: 46 | 47 | ```bash 48 | [user] 49 | name = spences10 50 | email = spences10apps@gmail.com 51 | ``` 52 | 53 | I'm not sure what other configuration options you may have in yours so 54 | we're just going to concentrate on the aliases, aliases can be used so 55 | that you can shorten the commands [or make them longer if you like] 56 | but I'm all for reducing key strokes, even if it is one or two less. 57 | 58 | So let's review the common commands I mentioned at the start: 59 | 60 | ```bash 61 | git add . 62 | git commit -m 'my awesome feature' 63 | git push 64 | ``` 65 | 66 | So with aliases we can shorten these down a bit: 67 | 68 | In your `.gitconfig` file if there's not already one there add in the 69 | `[aliases]` section, I have mine above my user details, then add in 70 | some aliases: 71 | 72 | ```bash 73 | [alias] 74 | a = add . 75 | c = commit -am 76 | p = push 77 | 78 | [user] 79 | name = spences10 80 | email = spences10apps@gmail.com 81 | ``` 82 | 83 | So now we can shorten down our workflow for adding a change to one of 84 | our repos: 85 | 86 | ```bash 87 | git add . 88 | git commit -m 'my awesome feature' 89 | git push 90 | ``` 91 | 92 | Will become: 93 | 94 | ```bash 95 | git a 96 | git c 'my awesome feature' 97 | git p 98 | ``` 99 | 100 | It's not a massive reduction in what you're typing but you'll be 101 | amazed at how quickly you become accustomed to it and start adding 102 | more an more. 103 | 104 | Here's my current list of aliases: 105 | 106 | ```bash 107 | [alias] 108 | a = add . 109 | b = branch 110 | c = commit -am 111 | cl = clone 112 | co = checkout 113 | d = diff 114 | f = fetch 115 | i = init 116 | o = open # see: https://github.com/paulirish/git-open ♥ 117 | p = push 118 | pt = push --tags 119 | s = status 120 | t = tag 121 | ``` 122 | 123 | A new one I have found out whilst making this post is 124 | `clone --depth 1` which clones only the HEAD of the repository instead 125 | of the whole repository, so say if you were cloning react you'd just 126 | get the master version rather than the other 38 branches included in 127 | the repository. Pretty neat 👍 so that could be aliased into something 128 | a lot shorter `git cl1d`? 129 | 130 | You'll no doubt notice the link I have in there for `o = open` that 131 | little gem belongs to [Paul Irish][pi] it's an npm package that will 132 | pop open a browser tab to the current repository you are in, pretty 133 | neat right? 134 | 135 | I'm sure there are many, many more ways to configure Git if you take a 136 | look at [Paul Irish][pidf]'s dotfiles repo for his `.gitconfig` you'll 137 | see there is a lot of ways to configure Git, I'm still learning and 138 | finding new ways to do things. 139 | 140 | If there is anything I have missed, or if you have a better way to dom 141 | something then please let me know 👍 142 | 143 | Get me on [Twitter][sdt] or [Ask Me Anything][ama] on GitHub 144 | 145 | If you like this post or if it has helped you in any way then please 146 | give it a like and don't forget to share it on social media 🙌 147 | 148 | 149 | 150 | [git-cheatsheet]: 151 | https://github.com/spences10/cheat-sheets/blob/master/git.md 152 | [toolsday]: http://www.toolsday.io/ 153 | [chris]: http://twitter.com/chrisdhanaraj 154 | [una]: http://twitter.com/una 155 | [git-tools]: http://www.toolsday.io/episodes/git.html 156 | [pi]: https://github.com/paulirish 157 | [pidf]: https://github.com/paulirish/dotfiles/blob/master/.gitconfig 158 | [sdt]: https://twitter.com/spences10 159 | [ama]: https://github.com/spences10/ama 160 | -------------------------------------------------------------------------------- /posts/2017/06/30/git-allow-unrelated-histories/git-compare-after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2017/06/30/git-allow-unrelated-histories/git-compare-after.png -------------------------------------------------------------------------------- /posts/2017/06/30/git-allow-unrelated-histories/git-compare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2017/06/30/git-allow-unrelated-histories/git-compare.png -------------------------------------------------------------------------------- /posts/2017/06/30/git-allow-unrelated-histories/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2017-06-30 3 | title: Git ` — allow-unrelated-histories` 4 | tags: ['information', 'guide'] 5 | private: false 6 | --- 7 | 8 | How to combine two separate unrelated Git repositories into one with 9 | single history timeline. 10 | 11 | Just adding a quick note on this… 12 | 13 | I had a project that started off as it’s own project but it ended up 14 | needing to go into an already existing project, so I thought ok add it 15 | as a new branch on the existing project with `git remote add origin` 16 | then push the changes up to the origin then all is well with the 17 | world. That was until I tried to compare the branches… 18 | 19 | ![compare](./git-compare.png) 20 | 21 | There isn't anything to compare? Bit misleading there as there is but 22 | the commit histories are different. How do you get around it, well the 23 | first Google result was a bit sparse with the details but then I found 24 | this which was more helpful. I needed to merge the disparate branches 25 | which is now disabled by default in git but can be enabled with the 26 | --allow-unrelated-histories flag. 27 | 28 | ```bash 29 | git merge origin use-ts-bot --allow-unrelated-histories 30 | ``` 31 | 32 | This brought up, understandably, a few conflicts with the branch I 33 | wanted to merge with the origin. 34 | 35 | ```bash 36 | Auto-merging package.json 37 | CONFLICT (add/add): Merge conflict in package.json 38 | Auto-merging package-lock.json 39 | CONFLICT (add/add): Merge conflict in package-lock.json 40 | Auto-merging README.md 41 | CONFLICT (add/add): Merge conflict in README.md 42 | Auto-merging .gitignore 43 | CONFLICT (add/add): Merge conflict in .gitignore 44 | Automatic merge failed; fix conflicts and then commit the result. 45 | ``` 46 | 47 | To get around this I just took the latest version of the `use-ts-bot` 48 | branch from my GitHub account and then and used that in place of the 49 | `origin` conflicts as what I’m working on will ultimately replace the 50 | master branch, so it was just a copy pasta into my VSCode then 51 | recommit the changes files. Phew! I now have a branch I can compare 52 | with the master that I will one day make a PR for 😅 53 | 54 | ![](./git-compare-after.png) 55 | -------------------------------------------------------------------------------- /posts/2018/01/13/wsl-bootstrap/bash-dotfiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2018/01/13/wsl-bootstrap/bash-dotfiles.png -------------------------------------------------------------------------------- /posts/2018/01/13/wsl-bootstrap/bash-wrong-perms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2018/01/13/wsl-bootstrap/bash-wrong-perms.png -------------------------------------------------------------------------------- /posts/2018/01/13/wsl-bootstrap/upgrade-yes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2018/01/13/wsl-bootstrap/upgrade-yes.png -------------------------------------------------------------------------------- /posts/2018/02/27/make-time-for-100doc/wakatime-stats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2018/02/27/make-time-for-100doc/wakatime-stats.png -------------------------------------------------------------------------------- /posts/2018/02/27/make-time-for-100doc/weight-gain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2018/02/27/make-time-for-100doc/weight-gain.png -------------------------------------------------------------------------------- /posts/2018/05/28/travis-ci/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2018-05-28 3 | title: Making a CI pipeline with Travis CI 4 | tags: ['information', 'guide', 'travis-ci', 'now', 'zeit'] 5 | private: false 6 | --- 7 | 8 | I thought I'd set up this blog with some sort of build pipeline, the 9 | intention was to have a good Continuous Integration pipeline so that 10 | if there were any issues when building the site that I wouldn't push a 11 | broken build. No one wants to see that 😿 12 | 13 | I'm feeling my way around with this and I'm presuming it's far from 14 | perfect or ideal even, but I have it as a functional work-flow. 15 | 16 | ### What I'm using 17 | 18 | - Zeit's now 19 | 20 | - Gatsby 21 | 22 | - Travis DUH! 23 | 24 | ### How the set-up works 25 | 26 | I have my GitHub project set up with two branches `master` and 27 | `development`, changes are made on feature branch of `development` 28 | then pushed into `development` then up to `master` once I'm happy the 29 | change is ok to go to production. 30 | 31 | Using [Zeit's now] you can define a different url for each of your 32 | environments. I have a `.now.sh` url for `development` and a 33 | sub-domain of my `scottspence.me` domain for `master`/production. 34 | 35 | ### The set-up 36 | 37 | There are a few parts to setting this up, the first is adding your 38 | repository to https://travis-ci.org/ then adding your `NOW_TOKEN` from 39 | https://zeit.co/account/tokens to the repository settings page on 40 | Travis-ci 41 | 42 | The [guide here] covers it for using now, the part I found 43 | particularly painful was generating the secure variable for the 44 | `.travis.yml` file because I don't have Ruby installed and I struggled 45 | to set it up on my OpenSUSE WSL install, so instead I used a Cloud9 46 | machine in the end. 47 | 48 | #### the flow 49 | 50 | Issue is "Add self hosted Fonts #75" I'll make a branch from git and 51 | give it a name to reflect the issue number 52 | `dev/75/add-self-hosted-fonts` I'll make my changes locally then push 53 | to the `development` branch. 54 | 55 | Once I have merged these changes into the `development` branch then I 56 | can view them om the `.now.sh` url configured in my `package.json` 57 | 58 | My `travis.yml` looks like this: 59 | 60 | ```yaml 61 | sudo: false 62 | 63 | language: node_js 64 | 65 | cache: 66 | directories: 67 | - node_modules 68 | 69 | notifications: 70 | email: false 71 | 72 | node_js: 73 | - '9' 74 | 75 | before_script: 76 | - npm prune 77 | 78 | script: 79 | - npm i -g now@canary 80 | - npm run clean 81 | - npm run build 82 | - npm run deploy 83 | 84 | after_script: 85 | - if [ "$TRAVIS_BRANCH" = "development" ]; then npm run alias:dev; 86 | fi 87 | - if [ "$TRAVIS_BRANCH" = "master" ]; then npm run alias:prod; fi 88 | - if [ "$TRAVIS_BRANCH" = "master" ]; then npm run release; fi 89 | - npm run cleanup 90 | 91 | env: 92 | global: 93 | secure: lngmfinghashvariable! 94 | ``` 95 | 96 | My `package.json` looks like this: 97 | 98 | ```json 99 | "now": { 100 | "name": "scottblog" 101 | }, 102 | "scripts": { 103 | "clean": "rm -rf .cache/ && rm -rf scottblog/ && rm -rf public/", 104 | "build": "gatsby build && mv public scottblog", 105 | "deploy:now": "npm run clean && npm run build && now scottblog/", 106 | "dev": "npm run clean && gatsby develop", 107 | "format": "pretty-quick", 108 | "precommit": "pretty-quick --staged", 109 | "deploy": "now scottblog/ --token $NOW_TOKEN", 110 | "alias:dev": "now alias blog-scottspence.now.sh --token $NOW_TOKEN", 111 | "alias:prod": "now alias blog.scottspence.me --token $NOW_TOKEN", 112 | "cleanup": "now rm scottblog --safe --yes --token $NOW_TOKEN", 113 | "release": "release-it" 114 | }, 115 | ``` 116 | 117 | [zeit's now]: https://zeit.co/now 118 | [guide here]: https://zeit.co/docs/examples/travis 119 | -------------------------------------------------------------------------------- /posts/2018/11/25/graphcms-to-gatsby/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2018-11-25 3 | title: Get your GraphCMS data into Gatsby 4 | tags: 5 | [ 6 | 'information', 7 | 'learning', 8 | 'guide', 9 | 'gatsby', 10 | 'getting started', 11 | 'graphql', 12 | 'graphcms', 13 | ] 14 | private: false 15 | --- 16 | 17 | Let's set up Gatsby to pull data from GraphCMS. 18 | 19 | 20 | 21 | This will be a walk-through of setting up some basic data on the 22 | headless CMS, GraphCMS and then querying that data in Gatsby. 23 | 24 | ## 1. Set up GraphCMS 25 | 26 | Set yourself up with a GraphCMS account at 27 | https://app.graphcms.com/signup and select the developer plan. 28 | 29 | ## 2. Define Data 30 | 31 | Create a new project and add in some data to query. 32 | 33 | Select the **Create new project** option, call it what you like, in 34 | this example it's going to be a list of projects, so I'm calling it 35 | _Project List_. 36 | 37 | In the side bar select the Schema and create a model, in this case 38 | **Project**. In the project model we're going to have a _Title_ and a 39 | _Description_. 40 | 41 | Select the fields from the tray on the right by clicking the 42 | **FIELDS** tab and dragging and dropping them into the **Project** 43 | model we created. 44 | 45 | ## 3. Configure the GraphCMS public API 46 | 47 | In the GraphCMS settings set the **Public API Permissions** to 48 | **READ** scroll down to **Endpoints** and copy the URL for use in 49 | configuring Gatsby. 50 | 51 | That's it for the CMS configuration, now to pull that data into our 52 | Gatsby frontend! 53 | 54 | ## 4. Configure Gatsby 55 | 56 | In you Gatsby project install `gatsby-source-graphql` and configure it 57 | in `gatsby-config.js` the configuration should looks something like: 58 | 59 | ```js 60 | { 61 | resolve: 'gatsby-source-graphql', 62 | options: { 63 | typeName: 'GRAPHCMS', 64 | fieldName: 'graphCmsData', 65 | url: 'https://api-euwest.graphcms.com/v1/projectid/master', 66 | } 67 | }, 68 | ``` 69 | 70 | In this example we're using [codesandbox.io] for our text editor and 71 | the Gatsby Default Starter you get when selecting Gatsby from the 72 | SERVER TEMPLATES available to you in [codesandbox.io] 73 | 74 | ## 5. Query the data in Gatsby GraphiQL 75 | 76 | Now that the endpoint is set up we will be able to query the data with 77 | Gatsby's GraphiQL UI, we can shape the query we want to use to display 78 | the data here. 79 | 80 | In the preview of our app in [codesandbox.io] if you add `___grapgql` 81 | to the end of the url it will bring up the Gatsby GraphiQL UI, here we 82 | can shape the data we want to query. 83 | 84 | If we open up some curly brackets `{}` and Cmd+space we'll see the 85 | available fields where we can pick out the `graphCmsData` field we 86 | defined in the `gatsby-source-graphql` plugin. 87 | 88 | Selecting the fields we created in GraphCMS then running the query 89 | will display our defined data. 90 | 91 | ```js 92 | { 93 | graphCmsData { 94 | projects { 95 | id 96 | status 97 | title 98 | description 99 | } 100 | } 101 | } 102 | ``` 103 | 104 | ## 6. Display the Data 105 | 106 | Use the `graphql` gatsby export to query the data from the GraphCMS 107 | endpoint. 108 | 109 | In `pages/index.js` add the `graphql` export the the `gatsby` imports. 110 | 111 | ```js 112 | import { graphql, Link } from 'gatsby' 113 | ``` 114 | 115 | At the very bottom define the query: 116 | 117 | ```js 118 | export const query = graphql` 119 | { 120 | graphCmsData { 121 | projects { 122 | id 123 | status 124 | title 125 | description 126 | } 127 | } 128 | } 129 | ` 130 | ``` 131 | 132 | You will then be able to access the `data` prop in the `IndexPage` 133 | component, we'll need to de-structure the `data` prop out in the 134 | arguments of the component: 135 | 136 | ```js 137 | const IndexPage = ({ data }) => ( 138 | ``` 139 | 140 | Now we can access the `data` passed into the component, we just need a 141 | way to visualise it! Luckily for use there's a handy component from 142 | Wes Bos that we can use called [Dump], so create a new `dump.js` 143 | component in `components` then import it into the `index.js` file, and 144 | add in the component to see what's inside the props: 145 | 146 | ```js 147 | const IndexPage = ({ data }) => ( 148 | 149 |

Hi people

150 | 151 |

Welcome to your new Gatsby site.

152 |

Now go build something great.

153 |
154 | 155 |
156 | Go to page 2 157 |
158 | ) 159 | ``` 160 | 161 | The output should be the same as the result of the Gatsby GraphiQL 162 | query we created: 163 | 164 | ```json 165 | data 💩{ 166 | "graphCmsData": { 167 | "projects": [ 168 | { 169 | "id": "cjoxa812txqoh0932hz0bs345", 170 | "status": "PUBLISHED", 171 | "title": "Project 1", 172 | "description": "Description 1" 173 | }, 174 | { 175 | "id": "cjoxa8cctxqqj0932710u39db", 176 | "status": "PUBLISHED", 177 | "title": "Project 2", 178 | "description": "Description 2" 179 | }, 180 | { 181 | "id": "cjoxa8pbqxqt309324z9bcddv", 182 | "status": "PUBLISHED", 183 | "title": "Project 3", 184 | "description": "Description 3" 185 | }, 186 | { 187 | "id": "cjoxa959vxqvz0932g1jn5ss3", 188 | "status": "PUBLISHED", 189 | "title": "Project 4", 190 | "description": "Description 4" 191 | } 192 | ] 193 | } 194 | } 195 | ``` 196 | 197 | [codesandbox.io]: https://codesandbox.io/dashboard/recent 198 | [dump]: https://github.com/wesbos/dump 199 | -------------------------------------------------------------------------------- /posts/2018/11/30/job-hunt-dev-project/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2018/11/30/job-hunt-dev-project/cover.jpg -------------------------------------------------------------------------------- /posts/2018/11/30/job-hunt-dev-project/jobsite-cv.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2018/11/30/job-hunt-dev-project/jobsite-cv.jpg -------------------------------------------------------------------------------- /posts/2019/01/27/multiple-git-profiles/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2019-01-27 3 | title: Setting up multiple Git providers 4 | tags: 5 | [ 6 | 'information', 7 | 'learning', 8 | 'guide', 9 | 'wsl', 10 | 'bash on windows', 11 | 'git', 12 | ] 13 | private: false 14 | --- 15 | 16 | Over the past couple of weeks now I have set up several development 17 | machines at work and have had to also use two git accounts, GitHib and 18 | Bitbucket. 19 | 20 | To connect to both I use SSH as a preference, I have been using SSH in 21 | place of HTTPS for quite some time now, if you want to connect 22 | repeatedly without having to provide user name and password details 23 | then SSH is a good option. 24 | 25 | If you are unfamiliar with using SSH to authenticate with git then 26 | take a look at my cheat sheets repository ([ss10.me/cheat-sheets]) 27 | there are several sections covering SSH, notably: 28 | 29 | - [How to Authenticate with GitHub Using SSH] 30 | - [Use multiple SSH Keys] (what this post is covering) 31 | - [Re Use SSH Keys from one Machine to Another] 32 | 33 | I have come across this set-up a few times now and implemented it for 34 | myself. 35 | 36 | You'll need to create a `config` file in the `.ssh` folder in your 37 | home directory (Windows, Ubuntu or both if you use a [WSL set-up]) 38 | check with: 39 | 40 | ```bash 41 | ll ~/.ssh/ 42 | ``` 43 | 44 | This will list out the contents of the folder, if you get 45 | `No such file or directory` then you don't have SSH configured. 46 | 47 | Take a look at the [How to Authenticate with GitHub Using SSH] section 48 | on the cheat-sheets repo for details on that. 49 | 50 | For this example let's presume that we have already created our SSH 51 | keys for Bitbucket and GitHub and authenticated with both Bitbucket 52 | and GitHub. 53 | 54 | Next create a `config` file: 55 | 56 | ```bash 57 | nano ~/.ssh/config 58 | ``` 59 | 60 | This will open a new file with nano that we can add the following to: 61 | 62 | ```bash 63 | # Bitbucket (default) 64 | Host bb 65 | HostName bitbucket.org 66 | User git 67 | IdentityFile ~/.ssh/id_default 68 | 69 | # Github (secondary) 70 | Host gh 71 | HostName github.com 72 | User git 73 | IdentityFile ~/.ssh/id_secondary 74 | ``` 75 | 76 | Just remember that the `IdentityFile` needs to match what you have 77 | called your SSH keys. 78 | 79 | Check current permissions with `stat`: 80 | 81 | ```bash 82 | # stat -c "%a %n" ~/.ssh/* 83 | 644 /home/scott/.ssh/config 84 | 700 /home/scott/.ssh/id_default 85 | 700 /home/scott/.ssh/id_default.pub 86 | 700 /home/scott/.ssh/id_secondary 87 | 700 /home/scott/.ssh/id_secondary.pub 88 | ``` 89 | 90 | Change the `config` file permissions as needed: 91 | 92 | ```bash 93 | chmod 644 ~/.ssh/config 94 | ``` 95 | 96 | ## Multiple users 97 | 98 | Ok now we should be able to push and pull to the respective GitHub and 99 | Bitbucket repositories, _but_ unless you have the same username and 100 | email address for GitHub and Bitbucket then we're also going to need 101 | to specify specific user details for the repositories we're accessing, 102 | otherwise the details specified in the `~/.gitconfig` are what will be 103 | used with commits. 104 | 105 | In my case for work my default user account is Bitbucket so that is 106 | what I have specified in the `~/.gitconfig`, however for the GitHub 107 | repos I work on I'll need to specify my GitHub credentials on a repo 108 | by repo basis. 109 | 110 | Historically I have gone into the individual repo and manually set the 111 | config details. 112 | 113 | ```bash 114 | # from the root of the repo you want to specify the credentials 115 | git config user.name 'Your Name' 116 | git config user.email 'your@email.com' 117 | ``` 118 | 119 | I have since found an ok solution here: 120 | https://stackoverflow.com/a/43654115/1138354 121 | 122 | Example: 123 | 124 | Global config `~/.gitconfig` 125 | 126 | ```bash 127 | 128 | [user] 129 | name = play.user 130 | email = play.user@gmail.com 131 | 132 | [includeIf "gitdir:~/work/"] 133 | path = ~/work/.gitconfig 134 | ``` 135 | 136 | Work specific config `~/work/.gitconfig` 137 | 138 | ```bash 139 | [user] 140 | name = work.user 141 | email = work.user@megacorp.ltd 142 | ``` 143 | 144 | 145 | 146 | [ss10.me/cheat-sheets]: https://github.com/spences10/cheat-sheets 147 | [how to authenticate with github using ssh]: 148 | https://github.com/spences10/cheat-sheets/blob/master/git.md#how-to-authenticate-with-github-using-ssh 149 | [use multiple ssh keys]: 150 | https://github.com/spences10/cheat-sheets/blob/master/git.md#use-multiple-ssh-keys 151 | [re use ssh keys from one machine to another]: 152 | https://github.com/spences10/cheat-sheets/blob/master/git.md#re-use-ssh-keys-from-one-machine-to-another 153 | [wsl set-up]: https://thelocalhost.io/wsl-bootstrap-2019 154 | -------------------------------------------------------------------------------- /posts/2019/03/09/testing-mdx/highlightVLive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2019/03/09/testing-mdx/highlightVLive.png -------------------------------------------------------------------------------- /posts/2019/03/09/testing-mdx/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2019-03-09 3 | title: Testing MDX 4 | tags: ['information', 'learning', 'gatsby', 'mdx'] 5 | private: false 6 | --- 7 | 8 | ## Moving to the new hotness!! 9 | 10 | I've now moved this blog over to Gatsby MDX. You can see all the 11 | changes 12 | [on my repo here](https://github.com/spences10/blog.scottspence.me/pull/1128/files). 13 | 14 | From the pull I'm hoping you can glean that the majority of the work 15 | is in replacing `gatsby-transformer-remark` with `gatsby-mdx`, there 16 | are some additional files added, that pretty nifty `Code.js` component 17 | from LekoArts minimal starter blog, and the `wrap-root-element.js` 18 | module for (I think) the MDX rendering of the code. 19 | 20 | Files changed: 21 | 22 | - `gatsby-browser.js` 23 | - `gatsby-config.js` 24 | - `gatsby-node.js` 25 | - `gatsby-ssr.js` 26 | - `src/pages/index.js` 27 | - `src/templates/blogPostTemplate.js` 28 | 29 | Files added: 30 | 31 | - `src/components/Code.js` 32 | - `wrap-root-element.js` 33 | 34 | Shout out to LekoArts, HagNerd and Chris Biscardi for their example 35 | repositories: 36 | 37 | - [gatsby-starter-minimal-blog](https://github.com/LekoArts/gatsby-starter-minimal-blog) 38 | - [gatsby-starter-blog-mdx](https://github.com/hagnerd/gatsby-starter-blog-mdx) 39 | - [christopherbiscardi.github.com](https://github.com/ChristopherBiscardi/christopherbiscardi.github.com) 40 | 41 | ## Things I still haven't figured out 42 | 43 | ### Code blocks 44 | 45 | Code blocks are pretty, this is a `js` block with the 46 | `prism-react-renderer/themes/nightOwl` theme: 47 | 48 | ```js 49 | const onClick = () => { 50 | alert('clicked') 51 | } 52 | render() 53 | ``` 54 | 55 | And here is a `js react-live` block, try editing the code: 56 | 57 | ```js react-live 58 | const onClick = () => { 59 | alert('clicked') 60 | } 61 | render() 62 | ``` 63 | 64 | Image for prosperity 👍 65 | 66 | ![](./highlightVLive.png) 67 | 68 | ### Mdx is a bit slow 69 | 70 | ### Sometimes renders don't update 71 | 72 | ### Not working yet 73 | 74 | - [ ] Autolink headers 75 | - [ ] Embed tweets 76 | - [ ] Embed videos 77 | -------------------------------------------------------------------------------- /posts/2019/03/09/testing-mdx/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2019/03/09/testing-mdx/index.png -------------------------------------------------------------------------------- /posts/2019/03/24/custom-gatsby-metadata-hook/compareLayout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2019/03/24/custom-gatsby-metadata-hook/compareLayout.png -------------------------------------------------------------------------------- /posts/2019/03/24/custom-gatsby-metadata-hook/compareSEO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2019/03/24/custom-gatsby-metadata-hook/compareSEO.png -------------------------------------------------------------------------------- /posts/2019/04/01/update-wsl-from-18.04-18.10/defaultRelaeaseUpgrader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2019/04/01/update-wsl-from-18.04-18.10/defaultRelaeaseUpgrader.png -------------------------------------------------------------------------------- /posts/2019/04/01/update-wsl-from-18.04-18.10/derp-install.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2019/04/01/update-wsl-from-18.04-18.10/derp-install.gif -------------------------------------------------------------------------------- /posts/2019/04/01/update-wsl-from-18.04-18.10/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2019-04-01 3 | title: Update Windows Subsystem Linux Ubuntu from 18.04 to 18.10 4 | tags: 5 | [ 6 | 'information', 7 | 'learning', 8 | 'wsl', 9 | 'guide', 10 | 'bash on windows', 11 | 'ubuntu', 12 | ] 13 | private: false 14 | --- 15 | 16 | ## Already use WSL with Ubuntu? Want an Upgrade?? 17 | 18 | This is a guide that will cover upgrading Windows Subsystem Linux 19 | (WSL) from the current LTS version to the latest 'normal' version 20 | 18.10. 21 | 22 | I found this post on [dev.to] this weekend detailing going from 23 | version 18.04 to 18.10 on Ubuntu for Windows Subsystem Linux. You will 24 | know form [earlier posts from me] that trying to go the update route 25 | on WSL is time consuming and you're basically better off starting 26 | again. 27 | 28 | I tried it myself and got in a bit of trouble, you can see by checking 29 | out the comments on [David's post] 30 | 31 | So from uninstalling my version of Ubuntu I went ahead and tried 32 | again, if you have read the comment's on [David's post] you'll see 33 | that I came up against an issue with being unable to reach the 'snap 34 | store'. I don't know what that is or means but basically it stopped my 35 | upgrade and I was left not knowing if I was fully upgraded or not. 36 | 37 | Thankfully someone else had come across the same problem and asked on 38 | [Stack Overflow], basically you need to uninstall Lxd with: 39 | 40 | ```bash 41 | sudo dpkg --force depends -P lxd; sudo dpkg --force depends -P lxd-client 42 | ``` 43 | 44 | Now we can go about updating Ubuntu with the `do-release-upgrade` 45 | command, if you do that right away you may see something along the 46 | lines of: 47 | 48 | ![no lts upgrade](./noLtsUpgrade.png) 49 | 50 | This is setting the updater to to only check for Long Term Support 51 | versions, we're going to change that now by changing the prompt from 52 | `lts` to `normal`, in bash use: 53 | 54 | ```bash 55 | sudo nano /etc/update-manager/release-upgrades 56 | ``` 57 | 58 | You should see the default release upgrader settings: 59 | 60 | ![default release ugrader](./defaultRelaeaseUpgrader.png) 61 | 62 | You'll need to set it to normal: 63 | 64 | ![default release ugrader](./normalRelaeaseUpgrader.png) 65 | 66 | Now we can go and do the release upgrade command: 67 | 68 | ```bash 69 | sudo do-release-upgrade 70 | ``` 71 | 72 | ## Upgrade time! 73 | 74 | Now I was quite surprised that it didn't _really_ take that long at 75 | all for the upgrade to complete, you may get asked questions about 76 | modified packages and weather you want to accept the maintainers or 77 | keep your version, I will always go with the maintainers version of 78 | any packages. You can do what you like with yours, I'm not your mum 😜 79 | 80 | ## That's it 81 | 82 | You should now have your Ubuntu WSL version at 18.10 👏 83 | 84 | ![update complete](./updateComlpete.png) 85 | 86 | If, like me, you uninstalled Ubuntu and tried to reinstall it and are 87 | getting errors like this: 88 | 89 | ![error installing ubuntu](./derp-install.gif) 90 | 91 | Then what worked for me was to restart the `LxssManager` via a 92 | PowerShell console with admin rights. 93 | 94 | ```powershell 95 | Get-Service LxssManager | Restart-Service 96 | ``` 97 | 98 | ## Wrap up! 99 | 100 | We went ahead an upgraded our WSL Ubuntu version from 18.04 to 18.10, 101 | we removed Lxd which isn't needed on WSL but is part of the Microsoft 102 | Store version 🤷‍♂️ 103 | 104 | Then we changed the default behaviour of the release upgrader from 105 | `lts` to `normal`. 106 | 107 | Once we have done those two parts we can then go ahead and upgrade 108 | Ubuntu with `do-release-upgrade. 109 | 110 | **Thanks for reading** 🙏 111 | 112 | Please take a look at my other content if you enjoyed this. 113 | 114 | Follow me on [Twitter] or [Ask Me Anything] on GitHub. 115 | 116 | 117 | 118 | [twitter]: https://twitter.com/spences10 119 | [ask me anything]: https://github.com/spences10/ama 120 | [dev.to]: https://dev.to 121 | [earlier posts from me]: 122 | https://thelocalhost.io/wsl-bootstrap-2019#update-upgrade-and-autoremove 123 | [david's post]: 124 | https://dev.to/david_j_eddy/how-to-upgrade-wsl-ubuntu-18-04-to-18-10-203 125 | [stack overflow]: 126 | https://askubuntu.com/questions/1119301/your-system-is-unable-to-reach-the-snap-store 127 | [codesandbox.io]: https://codesandbox.io 128 | [render props]: https://reactjs.org/docs/render-props.html 129 | [using the react context api]: 130 | http://localhost:8899/react-context-api-getting-started 131 | [example code]: https://codesandbox.io/s/1vnvko0zqj 132 | [even]: https://youtu.be/8ruJBKFrRCk?t=93 133 | [gatsby documentation]: 134 | https://www.gatsbyjs.org/docs/use-static-query/ 135 | -------------------------------------------------------------------------------- /posts/2019/04/01/update-wsl-from-18.04-18.10/noLtsUpgrade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2019/04/01/update-wsl-from-18.04-18.10/noLtsUpgrade.png -------------------------------------------------------------------------------- /posts/2019/04/01/update-wsl-from-18.04-18.10/normalRelaeaseUpgrader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2019/04/01/update-wsl-from-18.04-18.10/normalRelaeaseUpgrader.png -------------------------------------------------------------------------------- /posts/2019/04/01/update-wsl-from-18.04-18.10/updateComlpete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2019/04/01/update-wsl-from-18.04-18.10/updateComlpete.png -------------------------------------------------------------------------------- /posts/2019/07/19/jamstack-london-2019/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2019-07-19 3 | title: JAMstack_conf London 2019 4 | tags: ['conferences', 'jamstack'] 5 | private: false 6 | --- 7 | 8 | I've been wanting to go to a JAMstack conf since the first one was 9 | scheduled for October 2018. This year when it was announced there 10 | would be one in London I was super excited to get the opportunity to 11 | go. 12 | 13 | The conference was across two days with the first consisting of 14 | workshops, lightning talks and welcome drinks. The second was the 15 | keynote and conference talks either side of a lightning round with 16 | some exciting announcements. 17 | 18 | ## Tuesday - 2019-07-09 19 | 20 | First up was the workshop events where I was attending a workshop on 21 | schema stitching with GraphQL using GraphCMS and Moltin 22 | 23 | ## Workshop 24 | 25 | Jesse was a great at going through the basics of the headless CMS and 26 | why you should be using one. The workshop consisted of us defining our 27 | CMS content model with pen and paper before creating them in the 28 | GraphCMS UI for use with the Moltin eComerce API 29 | 30 | 31 | 32 | ### Technical difficulties 33 | 34 | There were issues on both the GraphCMS and the Moltin side, mainly 35 | around the UI for Moltin. We all managed to breeze through these 36 | keeping a good pace on the content. 37 | 38 | ### GraphQL Schema Stitching 39 | 40 | Once we all got through the initial setup on our projects it was quite 41 | satisfying to get to two schemas in one query. I still have a bit of 42 | work to do on my project as we all ran out of time towards the end. 43 | Jesse covered the main goal of the workshop which was to stitch the 44 | two schemas together. The additional UI work I can pick up at a later 45 | date. 46 | 47 | ## Lightning Talks 48 | 49 | After the workshops it was time for the lightening talks. 50 | 51 | [@jamiebradley234] did a talk on the booming tech scene in 52 | Middlesbrough. 53 | 54 | 55 | 56 | [@danfascia] did a great talk on how healthcare tech is benefiting 57 | from JAMstack methodologies. 58 | 59 | 60 | 61 | ## Wednesday - 2019-07-10 62 | 63 | ## Talks 64 | 65 | First up we had some apologies from Phill Hawksworth on behalf of 66 | Chris Coyer as Chris couldn't make it. We sent him a get well soon 67 | message. 68 | 69 | 70 | 71 | ### State of the JAMstack Nation - Sarah Drasner 72 | 73 | Sarah gave a demo of how quickly you could set up a JAMstack site, 74 | using Vue and Nuxt 75 | 76 | ### Netlify Analytics - Matt Biilmann 77 | 78 | Massive announcement for Netlify analytics I signed up there and then 79 | for my blog. Obviously Netlify is used to build Netlify so Matt showed 80 | off the continuous deployment for Netlify whilst putting the feature 81 | live. 82 | 83 | ### Transforming the Json - GROQ (& Sanity CMS) - Knut Melvær 84 | 85 | Knut showing off the advantages of using GROQ for querying your data. 86 | 87 | Also it's [now open source] 88 | 89 | ### Stackbit - Ben Edwards 90 | 91 | Ben announcing that Stackbit was coming out of beta. Stackbit is a 92 | great all in one tool for making JAMstack sites with CMS integration. 93 | 94 | ### Code Sandbox. - Ives van Horne 95 | 96 | Ives (Flip) went into how he made [codesandbox.io] whils being a 97 | college student. 98 | 99 | If you want something build cheaply, ask a student to build it for you 100 | was the take home here for me. 101 | 102 | ### Why & How Smashing Magazine moved to JAMstack - Vitaly Friedman 103 | 104 | Brilliant talks from Vitaly on the transition of Smashing Mag from 105 | monolith over to the JAMstack. Also great detail on the redesign. 106 | 107 | ### WeWorkLabs moves to JAMstack - Ramin Bozorgzadeh 108 | 109 | JAMstack helps me sleep at night! 110 | 111 | ### CSS Houdini Today - Una Kravets 112 | 113 | Una was super jazzed about Houdini, you could do some pretty neat css 114 | tricks with it. 115 | 116 | [https://extra-css.netlify.com/] 117 | 118 | ### Serverless functions - Simona Cotin 119 | 120 | Simona detailed key usecases for serveless functions. 121 | 122 | ### Performance optimizing and Webpack bashing - Jake Archibald and Surma 123 | 124 | Surma and Jake went through how to optimise a modern day minesweeper 125 | game for mobile. 126 | 127 | **"Should I worry about performance?"** 128 | 129 | **Answer: YES!** 130 | 131 | Hosted web fonts slow things down, because the browser has to load 132 | from multiple servers. Optimize further by only including the 133 | characters you need. Use css, assets, fonts directly in the HTML to 134 | eliminate needing additional requests. 135 | 136 | Here's the repo: [https://github.com/GoogleChromeLabs/proxx] 137 | 138 | ### Hot! 139 | 140 | Being in the UK we had the British weather to content with and the 141 | venue although fitted with A/C units in the speaker hall the venue 142 | outside of that was hot and sweaty! I spent the majority of my time 143 | between talks situated directly in front of the A/C units. 144 | 145 | 146 | 147 | 148 | 149 | ## That's it folks! 150 | 151 | This was a great event I met a lot of new people and several Twitter 152 | friends. I can't wait until the next one. 153 | 154 | 155 | 156 | [@danfascia]: https://twitter.com/danfascia 157 | [@jamiebradley234]: https://twitter.com/jamiebradley234 158 | [codesandbox.io]: https://codesandbox.io 159 | [https://github.com/googlechromelabs/proxx]: 160 | https://github.com/GoogleChromeLabs/proxx 161 | [https://extra-css.netlify.com/]: https://extra-css.netlify.com/ 162 | [now open source]: 163 | https://www.sanity.io/blog/we-re-open-sourcing-groq-a-query-language-for-json-documents 164 | -------------------------------------------------------------------------------- /posts/2019/10/31/build-an-mdx-blog/draw-a-horse-quincy-tweet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2019/10/31/build-an-mdx-blog/draw-a-horse-quincy-tweet.png -------------------------------------------------------------------------------- /posts/2019/11/06/react-advanced-london-2019/anything.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2019/11/06/react-advanced-london-2019/anything.png -------------------------------------------------------------------------------- /posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/01.current-version.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/01.current-version.png -------------------------------------------------------------------------------- /posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/02.do-release-upgrade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/02.do-release-upgrade.png -------------------------------------------------------------------------------- /posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/03.release-upgrades-normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/03.release-upgrades-normal.png -------------------------------------------------------------------------------- /posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/04.release-upgrade-for-realsies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/04.release-upgrade-for-realsies.png -------------------------------------------------------------------------------- /posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/05.upgrade-confirmation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/05.upgrade-confirmation.png -------------------------------------------------------------------------------- /posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/06.config-libc6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/06.config-libc6.png -------------------------------------------------------------------------------- /posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/07.lxd-warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/07.lxd-warning.png -------------------------------------------------------------------------------- /posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/08.openssh-servier-config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/08.openssh-servier-config.png -------------------------------------------------------------------------------- /posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/09.release-upgrades-config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/09.release-upgrades-config.png -------------------------------------------------------------------------------- /posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/10.finish-up-install.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/10.finish-up-install.png -------------------------------------------------------------------------------- /posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/11.restart-prompt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/11.restart-prompt.png -------------------------------------------------------------------------------- /posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/12.finish-upgrade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/12.finish-upgrade.png -------------------------------------------------------------------------------- /posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/13.press-x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/13.press-x.png -------------------------------------------------------------------------------- /posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/14.done.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/14.done.png -------------------------------------------------------------------------------- /posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2020-01-28 3 | title: Upgrade Windows Subsystem Linux - Ubuntu 18.04 to Ubuntu 19.10 4 | tags: ['information', 'wsl', 'guide', 'bash on windows', 'ubuntu'] 5 | private: false 6 | --- 7 | 8 | In this guide I'm going to detail upgrading a Windows Subsystem Linux 9 | (WSL) Ubuntu install from the current version 18.04 to 19.10 this is 10 | an intermediary release before Ubuntu 20.04 is released on 2020 11 | April 23. 12 | 13 | I have documented [this process in the past] for moving from Ubuntu 14 | version 18.04 to 18.10. You can see [my comments] as I went through 15 | the process back then. 16 | 17 | ## 📺 Here's a video detailing the process. 18 | 19 | 20 | 21 | ## Check the current Ubuntu version 22 | 23 | Ok, to check the current installed version of Ubuntu from the terminal 24 | I enter `lsb_release -a` to get the currently installed Ubuntu version 25 | displayed. 26 | 27 | > LSB stands for Linux Standard Base and the '-a' is for 'all 28 | > information' 29 | 30 | ```bash 31 | lsb_release -a 32 | ``` 33 | 34 | The output looks like this: 35 | 36 | ![](./01.current-version.png) 37 | 38 | ## Do the release upgrade! 39 | 40 | To start the upgrade I enter the terminal command 41 | `do-release-upgrade`. 42 | 43 | ```bash 44 | sudo do-release-upgrade 45 | ``` 46 | 47 | ![](./02.do-release-upgrade.png) 48 | 49 | This will prompt me if my `release-upgrades` file isn't set to 50 | `normal`. 51 | 52 | ## Set release upgrades to normal 53 | 54 | Open the `release-upgrades` file path to edit, in this example I'm 55 | using [Nano] to edit the file. 56 | 57 | ```bash 58 | sudo nano /etc/update-manager/release-upgrades 59 | ``` 60 | 61 | In the file I change the `Prompt` from `Prompt=lts` to 62 | `Prompt=normal`. 63 | 64 | ![](./03.release-upgrades-normal.png) 65 | 66 | To save the file in Nano I use Ctrl+o to write out the file, confirm 67 | (Enter/Return) then to close use I Ctrl+x. 68 | 69 | ## Do the release upgrade, for realsies 70 | 71 | Now the `release-upgrades` file is set to `normal` I can do the 72 | [do-release-upgrade]. 73 | 74 | ![](./04.release-upgrade-for-realsies.png) 75 | 76 | You may be aware of an [lxd error] that occurs on the Ubuntu 18.04 to 77 | Ubuntu 18.10 upgrade. This is where there is a prompt saying ["Your 78 | system is unable to reach the snap store"]. 79 | 80 | I'm going to skip this during the upgrade but you can _**optionally**_ 81 | run this when doing this for yourself, here's the command: 82 | 83 | ```bash 84 | sudo dpkg --force depends -P lxd; sudo dpkg --force depends -P lxd-client 85 | ``` 86 | 87 | Pick the same command again in the terminal, if I arrow up a a couple 88 | of commands I can use it again. 89 | 90 | ```bash 91 | sudo do-release-upgrade 92 | ``` 93 | 94 | I'm now prompted with the details of what is going to happen in the 95 | upgrade: 96 | 97 | ![](./05.upgrade-confirmation.png) 98 | 99 | I respond with `y` to continue and start the upgrade. 100 | 101 | ## Warnings and configs 102 | 103 | When I'm prompted about `libc6` for restarting services during package 104 | upgrades I use the tab key to select `` then return to continue. 105 | 106 | ![](./06.config-libc6.png) 107 | 108 | Next I have the `Lxd` warning I mentioned earlier, in this case I'm 109 | going to arrow down and select the option to `` then hit return 110 | to continue. 111 | 112 | ![](./07.lxd-warning.png) 113 | 114 | In the following screens I'm being asked about package configuration, 115 | I'm going to be picking the option to 116 | `install the package maintainer's version` for all of them. 117 | 118 | Same with `openssh-server` arrow up key to to 119 | `install the package maintainer's version` and hit return to continue. 120 | 121 | ![](./08.openssh-servier-config.png) 122 | 123 | Then there's the `release-upgrades` configuration and yeah I'm going 124 | to select to `install the package maintainer's version` and confirm to 125 | continue. 126 | 127 | ![](./09.release-upgrades-config.png) 128 | 129 | ## Finish up install 130 | 131 | One of the last few prompts is to confirm the removal of the obsolete 132 | packages, confirm `y` to continue. 133 | 134 | ![](./10.finish-up-install.png) 135 | 136 | Restart is required now, so I confirm with `y`. 137 | 138 | ![](./11.restart-prompt.png) 139 | 140 | Now I have the confirmation that the do release upgrade completed 141 | successfully. I press Ctrl+c 142 | 143 | ![](./12.finish-upgrade.png) 144 | 145 | Then have to press `x` to destroy! 146 | 147 | ![](./13.press-x.png) 148 | 149 | That takes me back to the regular prompt where I can check with 150 | `lsb_release -a` what version I'm now on. 151 | 152 | ![](./14.done.png) 153 | 154 | Confirmation the Windows Subsystem Linux version of Ubuntu I'm using 155 | is now on 19.10. 156 | 157 | ## Wrap up! 158 | 159 | That's it! I upgraded a WSL Ubuntu version from 18.04 to 19.10. 160 | 161 | First, I changed the default behaviour of the release upgrader from 162 | `lts` to `normal`. 163 | 164 | Then `do-release-upgrade`, and I skipped the `Lxd` configuration. It 165 | isn't needed on WSL but is part of the Ubuntu image on the Microsoft 166 | Store 🤔 167 | 168 | I accept `install the package maintainer's version` on any 169 | configuration prompts. 170 | 171 | Done. 172 | 173 | ## Thanks for reading 🙏 174 | 175 | Please take a look at my other content if you enjoyed this. 176 | 177 | Follow me on [Twitter] or [Ask Me Anything] on GitHub. 178 | 179 | 180 | 181 | [twitter]: https://twitter.com/spences10 182 | [ask me anything]: https://github.com/spences10/ama 183 | [this process in the past]: 184 | https://thelocalhost.io/2019/04/01/update-wsl-from-18.04-18.10/ 185 | [my comments]: https://dev.to/spences10/comment/9n19 186 | [do-release-upgrade]: 187 | https://help.ubuntu.com/lts/serverguide/installing-upgrading.html 188 | [nano]: https://help.ubuntu.com/community/Nano 189 | [lxd error]: https://dev.to/spences10/comment/9n3j 190 | ["your system is unable to reach the snap store"]: 191 | https://askubuntu.com/questions/1119301/your-system-is-unable-to-reach-the-snap-store 192 | -------------------------------------------------------------------------------- /posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/updateComlpete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/01/28/update-wsl-ubuntu-from-18.10-to-19.10/updateComlpete.png -------------------------------------------------------------------------------- /posts/2020/02/06/globally-style-gatsby-styled-components/reset-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/02/06/globally-style-gatsby-styled-components/reset-page.png -------------------------------------------------------------------------------- /posts/2020/04/16/fathom-create-custom-domain/create-new-dns-record-netlify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/04/16/fathom-create-custom-domain/create-new-dns-record-netlify.png -------------------------------------------------------------------------------- /posts/2020/04/16/fathom-create-custom-domain/fathom-dns-record-for-site.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/04/16/fathom-create-custom-domain/fathom-dns-record-for-site.png -------------------------------------------------------------------------------- /posts/2020/04/16/fathom-create-custom-domain/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2020-04-16 3 | title: Create a Custom Domain for Fathom Analytics 4 | tags: ['analytics', 'learning', 'guide'] 5 | private: false 6 | --- 7 | 8 | Fathom Analytics recently added a really neat feature for [custom 9 | domains] with their service. 10 | 11 | What does that mean then? Well it's for bypassing ad-blocking 12 | extensions, not that Fathom wants to collect all your data, [far from 13 | it]. 14 | 15 | The purpose of this post is to cover setting up my custom domain as I 16 | have a specific domain provider and I'm using Vercel's now.sh and 17 | Netlify for hosting my projects I want to add the Fathom custom 18 | domains to. 19 | 20 | Fathom has provided instructions for [Godaddy], [CloudFlare], [Hover] 21 | and [NameCheap] however, Like I mentioned, I have a custom DNS with my 22 | domain provider and I'm not be able to add a new CNAME record which is 23 | what I need to generate my Fathom custom (sub)domain. 24 | 25 | ## Create a custom domain 26 | 27 | Fathom's [documentation] covers it pretty well, you go into your 28 | settings panel on Fathom and add in the domain of your site which I 29 | followed, pretty straight forward. 30 | 31 | Fathom then give me two values, the first is the sub-domain that I'm 32 | going to create and the other is the Fathom DNS server. 33 | 34 | ![fathom dns record for a site] 35 | 36 | ## Add the custom domain to my site 37 | 38 | I set about working out how to add a CNAME to this blog but couldn't 39 | find any good examples so I reached out to Fathom with a tweet: 40 | 41 | 42 | 43 | After I sent that I found [this gist] which detailed the command for 44 | adding the sub-domain which made sense to me. 45 | 46 | ## Add DNS record in Vercel's now.sh 47 | 48 | With the two values from Fathom dashboard, the CNAME is the sub-domain 49 | and the VALUE is the DNS server. 50 | 51 | So in the now CLI I did the following: 52 | 53 | ```bash 54 | now dns add randomsite.com cdrjcy CNAME starman.fathomdns.com 55 | ``` 56 | 57 | Then I checked that the changes were added using the now dns command 58 | to list out my DNS settings: 59 | 60 | ```bash 61 | now dns ls 62 | ``` 63 | 64 | It depends on how quickly these are propagated to see if the record is 65 | created, for me it was a refresh on the Fathom dashboard and it said 66 | the domain was active with a couple of emails from Fathom to confirm 67 | they were created. 68 | 69 | ## DNS Editor for Vercel domains 70 | 71 | It was after I worked out how to add the CNAME with the CLI that I 72 | found the [DNS Editor for Vercel domains] which Jack mentioned in the 73 | reply to my tweet! 🤦‍♂ 74 | 75 | It's a free integration on the Vercel Marketplace which is super 76 | straightforward to use once you add it to your Vercel account you can 77 | pick it from the Integrations section on your Vercel Dashboard. 78 | 79 | ## Select custom domain in site settings 80 | 81 | Now that the domain is set up I need to select that in the Sites 82 | dashboard, click on the Site ID for my site the pick the domain from 83 | the select list and verify it's working on my site that is already 84 | configured with Fathom. 85 | 86 | ![pick custom domain in site settings] 87 | 88 | ## Add DNS record in Netlify 89 | 90 | I'm going to do the same with Netlify now, it's a bit more 91 | straightforward with Netlify, I go to my sites page, select Domains, 92 | pick my domain scroll to the bottom of the list and select 'Add new 93 | record', add the details from the Fathom Domains page. 94 | 95 | ![create new dns record netlify] 96 | 97 | It didn't take long to validate the record in the Fathom setting page 98 | then I picked the custom domain like I did in the previous step. 99 | 100 | ## Configure Gatsby to use the custom domain 101 | 102 | Fathom have now added instructions for adding the Fathom tracking 103 | snippet [to your Gatsby site]. 104 | 105 | This involves customising the Gatsby [`default-html.js` file] and 106 | adding the snippet before the `` starts. 107 | 108 | So for me, following the Fathom instructions, copy the 109 | `default-html.js` file from the `.cache` directory to the `src` 110 | directory: 111 | 112 | ```bash 113 | cp .cache/default-html.js src/html.js 114 | ``` 115 | 116 | That command presumes that the Gatsby develop command has been run at 117 | least once so the `.cache` directory has been created. 118 | 119 | So now go to the `default-html.js` file and add in the Fathom snippet, 120 | here's what it should look like: 121 | 122 | ```js 123 | import PropTypes from 'prop-types' 124 | import React from 'react' 125 | 126 | export default function HTML(props) { 127 | return ( 128 | 129 | 135 | 136 | 137 | ... 138 | ``` 139 | 140 | Now that's there I can build the site locally and test the analytics 141 | is working. 142 | 143 | ## Remove `gatsby-plugin-fathom` 144 | 145 | Now that I'm using the `default-html.js` for the Fathom snippet 146 | there's no need to have the Gatsby plugin for Fathom installed, so 147 | that's one less plugin to have installed. 148 | 149 | Done! 150 | 151 | 152 | 153 | [custom domains]: https://usefathom.com/blog/bypass-adblockers 154 | [far from it]: https://usefathom.com/blog/bypass-adblockers 155 | [documentation]: https://usefathom.com/support/custom-domains 156 | [godaddy]: https://ca.godaddy.com/help/add-a-cname-record-19236 157 | [cloudflare]: 158 | https://support.cloudflare.com/hc/en-us/articles/360020615111-Configuring-a-CNAME-setup 159 | [hover]: 160 | https://help.hover.com/hc/en-us/articles/217282457-Managing-DNS-records-#h_5eab4aa7-b044-4cc6-a3c0-5869f583edc8 161 | [namecheap]: 162 | https://www.namecheap.com/support/knowledgebase/article.aspx/9646/2237/how-to-create-a-cname-record-for-your-domain 163 | [this gist]: 164 | https://gist.github.com/jaydenseric/f4147d7d9788d1f46b30e4ac7b57e6b2 165 | [dns editor for vercel domains]: https://vercel.com/integrations/dns 166 | [fathom dns record for a site]: ./fathom-dns-record-for-site.png 167 | [pick custom domain in site settings]: 168 | ./pick-custom-domain-in-site-settings.png 169 | [create new dns record netlify]: ./create-new-dns-record-netlify.png 170 | [to your gatsby site]: https://usefathom.com/integrations/gatsbyjs 171 | [`default-html.js` file]: https://www.gatsbyjs.org/docs/custom-html/ 172 | -------------------------------------------------------------------------------- /posts/2020/04/16/fathom-create-custom-domain/pick-custom-domain-in-site-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/04/16/fathom-create-custom-domain/pick-custom-domain-in-site-settings.png -------------------------------------------------------------------------------- /posts/2020/04/18/add-tracking-links-to-your-markdown/url-with-goalid-showing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/04/18/add-tracking-links-to-your-markdown/url-with-goalid-showing.png -------------------------------------------------------------------------------- /posts/2020/04/19/url-shortener-with-nowsh/vercel-domains-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/04/19/url-shortener-with-nowsh/vercel-domains-settings.png -------------------------------------------------------------------------------- /posts/2020/04/19/url-shortener-with-nowsh/vercel-project-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/04/19/url-shortener-with-nowsh/vercel-project-overview.png -------------------------------------------------------------------------------- /posts/2020/04/25/custom-email-domain-with-now/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2020-04-25 3 | title: Configure Custom Domain Email with Zoho and Now 4 | tags: ['information', 'guide', 'now', 'domains'] 5 | private: false 6 | --- 7 | 8 | In this guide I'm going to cover the configuring of your custom domain 9 | with Vercel's Now platform using the Now CLI. 10 | 11 | I'll be primarily covering the steps you take after setting up an 12 | account with an email provider, the email provider I'm using is [Zoho 13 | Mail] if you don't use either of these services then this guide may 14 | not be much use to you. 15 | 16 | ## What you'll need 17 | 18 | - a super awesome custom domain 19 | - a [Zoho Mail] account 20 | - a [Vercel.co] account 21 | - The [Now CLI] installed 22 | 23 | It's implied that you have a machine set up for web development 24 | already and are familiar with using the terminal. 25 | 26 | If you need to get set up for Windows [I have written a guide] 27 | previously on that topic. 28 | 29 | If you're a Linux user, check out this video on getting set up: 30 | 31 | 32 | 33 | ## Set up an account 34 | 35 | Zoho mail offer a 5 GB [forever free plan], so as long as you can 36 | manage your email archiving then you are good to go. 37 | 38 | You also get up to five users and a 25mb file attachment limit with 39 | hosting for a single domain. 40 | 41 | Pretty good right! 42 | 43 | ## Create an admin super user 44 | 45 | When you sign up with [Zoho Mail] you will be prompted to create a 46 | super admin user for your zoho account and you're given the 47 | opportunity to set up two factor authentication (2fa). 48 | 49 | Zoho will even tell you about their authenticator app, which is only 50 | for authenticating with Zoho. Use this is you like, I use a 2fa app 51 | that you can use for multiple services. 52 | 53 | ## Verify you own the domain 54 | 55 | You will be given a code to verify that you are the owner of the 56 | domain, which you will need to add as a `TXT` entry on your domain 57 | with the Now CLI. 58 | 59 | The verification token will look something like this: 60 | 61 | ```bash 62 | zoho-verification=se4567894.zmverify.zoho.eu 63 | ``` 64 | 65 | Add that to your domain DNS with the Now CLI, you can check your 66 | domain DNS entries with the `ls` command. 67 | 68 | ```bash 69 | # list your dns entries 70 | now dns ls yourdomain.com 71 | # add the zoho verification as a TXT record 72 | now dns add yourdomain.com @ TXT zoho-verification=se4567894.zmverify.zoho.eu 73 | ``` 74 | 75 | ## Add the MX records 76 | 77 | Now to configure the `MX` records. MX records are essential to receive 78 | emails in your domain. The MX records for your domain will look 79 | something like this: 80 | 81 | | Host Name | Address | Priority | 82 | | --------- | ----------- | -------- | 83 | | @ / Blank | mx.zoho.eu | 10 | 84 | | @ / Blank | mx2.zoho.eu | 20 | 85 | | @ / Blank | mx3.zoho.eu | 50 | 86 | 87 | Add them much in the same way as with the verification token with the 88 | Now CLI this time specifying an `MX` instead of `TXT` and there's a 89 | second argument for the priority: 90 | 91 | ```bash 92 | now dns add yourdomain.com @ MX mx.zoho.eu 10 93 | now dns add yourdomain.com @ MX mx.zoho.eu 20 94 | now dns add yourdomain.com @ MX mx.zoho.eu 50 95 | ``` 96 | 97 | ## Set the Sender Policy Framework (SPF) 98 | 99 | To ensure that valid emails from your domain get delivered to your 100 | users, and spoofed emails from other spammers are identified by the 101 | other email services, it's recommend you add an SPF record for your 102 | domain. 103 | 104 | This will go into a `TXT` record like with the verification token: 105 | 106 | ```bash 107 | now dns add yourdomain.com @ TXT 'v=spf1 include:zoho.eu ~all' 108 | ``` 109 | 110 | **Note: You may need to wait a while after making these changes before 111 | the DNS updates can be verified via Zoho.** 112 | 113 | 114 | 115 | [vercel.co]: https://vercel.com/signup 116 | [zoho mail]: https://www.zoho.com/mail/ 117 | [dns integration]: https://vercel.com/integrations/dns 118 | [domains]: https://vercel.com/domains 119 | [now cli]: https://vercel.com/download 120 | [pricing]: https://www.zoho.com/mail/zohomail-pricing.html 121 | [control panel settings]: 122 | https://mail.zoho.eu/cpanel/index.do#orgsettings/config 123 | [i have written a guide]: 124 | https://thelocalhost.io/2018/12/24/wsl-bootstrap-2019/ 125 | [forever free plan]: https://workplace.zoho.eu/orgsignup.do 126 | -------------------------------------------------------------------------------- /posts/2020/04/27/a-digital-garden/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2020-04-27 3 | title: A Digital Garden 4 | tags: ['information', 'guide', 'now', 'domains'] 5 | private: false 6 | --- 7 | 8 | I spent a couple of days now questioning how and what I write after 9 | reading a [post from Richard Haines]. In his post he mentioned how he 10 | stumbled across the Digital Garden idea. 11 | 12 | Richard's post led me to [Chris Biscardi's thoughts] on that and in 13 | turn [Joel Hooks] and his thoughts on it. 14 | 15 | Both Joel and Chris mention a post from [Amy Hoy] (who I've just 16 | realised I follow on Twitter) in the post Amy talks about the [How the 17 | Blog Broke the Web] 18 | 19 | All of this was quite thought provoking! 20 | 21 | ## Paradigm shift 22 | 23 | I decided that where I write about what I learn doesn't have to be a 24 | job, something else to add to my current cognitive load. It should be 25 | a place where I do things for me, for future me. 26 | 27 | The content here is primarily for me to document what I've learned. If 28 | it helps anyone else then that's a massive plus, also, you're welcome. 29 | 🐱 30 | 31 | ## Side effects 32 | 33 | This shift in thinking triggered a lot of activity here! 34 | 35 | I spent some time cleaning up the site, I removed all unnecessary 36 | cover images. 37 | 38 | I felt that this really didn't add anything to the content, the images 39 | were unrelated and added nothing and were only really there for social 40 | sharing to use the Open Graph images. 41 | 42 | So, the posts folder on this site before and after I purged all the 43 | assets: 44 | 45 | - 70mb folder size with cover images 46 | - 47mb after removing images 47 | 48 | That was ok, however, I've now got the posts folder down to **4.3mb** 49 | after [Moving Large Markdown Assets to a CDN] and the project builds 50 | 25% faster! 51 | 52 | There's still social sharing cards, now they are [generated with a 53 | serverless function], which was another great learning experience! 54 | 55 | That is another thing to come out of this paradigm shift and how I'm 56 | going to do things in _my_ Digital Garden, a site that builds 25% 57 | faster than before. 58 | 59 | I'll go into more detail on this in the upcoming post [Moving from Now 60 | to Netlify then back to Now], I think the title explains a lot of what 61 | the content will be on that one. 62 | 63 | ## The way it's going to be 64 | 65 | So this is going to work with the notion that I'll write about things 66 | as they come to me, add them here and add to them periodically as and 67 | when needed. 68 | 69 | So far there are five posts that have come out of this, I unpublished 70 | everything but soon put them back behind a published flag as there 71 | were a lot of half arsed posts, some just a title and a link. 72 | 73 | If you're reading this and wondering why there's a post titled 74 | **Shaving the Yak!** with the total content of one sentence and two 75 | links! **Sorry**. 76 | 77 | ## A theme switch 78 | 79 | Sometimes migrating all your local assets to a CDN and adding a theme 80 | switcher on your projects can generate quite a lot of ideas and you 81 | can learn a lot from it. 82 | 83 | This site now has [styled scrollbars], serverless OG images and a 84 | theme switcher all thanks to me reading one post! 85 | 86 | I've never been so busy with taking notes and documenting how I've 87 | done a thing or what I've learned after doing that thing. 88 | 89 | ## Conclusion 90 | 91 | I'm still in the midst of what I'm going to do, but I am doing away 92 | with the `.blog` TLD, I did like the idea of an `.io` TLD but have 93 | since found that it's origins have quite a [sinister background] that 94 | I really want no part of. 95 | 96 | I do like the idea of the site's name and I guess I had grand ideas of 97 | having guests come and write posts on here too. Let's face it though, 98 | anyone doing that is going to use their own platform. 99 | 100 | I'm more than likely going to move all these posts back to my own 101 | personal site and share things from there. 102 | 103 | There's going to be a lot of work involved in doing that and right now 104 | I want to focus more on getting ideas out of my head, and somewhere 105 | else (here) so I can get on with other tasks and leave the ideas to 106 | build and peculate. 107 | 108 | Get it down then get it done! 109 | 110 | 111 | 112 | [post from richard haines]: https://richardhaines.dev/on-my-mind/ 113 | [joel hooks]: https://joelhooks.com/digital-garden 114 | [chris biscardi's thoughts]: 115 | https://www.christopherbiscardi.com/what-is-a-digital-garden 116 | [amy hoy]: https://twitter.com/amyhoy 117 | [how the blog broke the web]: 118 | https://stackingthebricks.com/how-blogs-broke-the-web/ 119 | [building a digital garden]: 120 | https://tomcritchlow.com/2019/02/17/building-digital-garden/ 121 | [moving from now to netlify then back to now]: 122 | https://thelocalhost.io/2020/05/02/moving-from-now-to-netlify/ 123 | [moving large markdown assets to a cdn]: 124 | https://thelocalhost.io/2020/04/30/large-md-assets-to-cdn/ 125 | [generated with a serverless function]: 126 | https://thelocalhost.io/2020/04/30/serverless-og-images/ 127 | [sinister background]: 128 | https://gigaom.com/2014/06/30/the-dark-side-of-io-how-the-u-k-is-making-web-domain-profits-from-a-shady-cold-war-land-deal/ 129 | [styled scrollbars]: 130 | https://css-tricks.com/the-current-state-of-styling-scrollbars/ 131 | -------------------------------------------------------------------------------- /posts/2020/04/27/continus-deployment/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2020-04-27 3 | title: Continuous Deployments on Non Essential Projects 4 | tags: ['information', 'guide', 'now', 'domains'] 5 | private: false 6 | --- 7 | 8 | Quite a while ago now I was introduced to dependency update tools like 9 | Renovate and Greenkeeper, at the time I thought they were awesome, 10 | keeping your projects patched and secure so I went and used them in 11 | _every_ project I made. 12 | 13 | ## Busy work 14 | 15 | Some of my GitHub projects has a ridiculous amount of commits on them. 16 | I remember pointing [Jamie Barton] to a project I did to make a 17 | dynamic [navigation bar with GraphCMS] and he commented on the amount 18 | of commits ~1.5k commits. I'd say about 99% of those were dependency 19 | updates from the Renovate bot, it's bonkers! 20 | 21 | One of the main reasons for using Renovate was for keeping the project 22 | up to date when I wasn't working on it. I haven't done anything with 23 | it for years! 24 | 25 | So there's this long list of dependency updates on a project that's 26 | not in production which I haven't worked on in years. 27 | 28 | I guess I thought I can keep it updated for when I eventually get 29 | round to working on it again and just merge any updates as and when 30 | they're made. 31 | 32 | I had this whole strategy of a `patch` branch that I'd merge into a 33 | `develop` branch that would eventually make it's way into `master` the 34 | thing is, if I wanted to find a specific commit I'd be wading through 35 | hundreds of commits from a bot. 36 | 37 | ## Great tool 38 | 39 | Renovate is an awesome tool with fantastic configuration that you can 40 | use to effectively keep your dependencies up to date. On the creation 41 | of each of my GitHub projects there's a default checkbox for Renovate 42 | which I'd think yeah cool, better keep it updated. 43 | 44 | ## Noisy 45 | 46 | That's great n' all but when you also have a GitHub build integration 47 | like the Netlify or Vercel integrations to build new PRs when there's 48 | a new release then things start to go south. 49 | 50 | With Netlify if your a non pro user you get 300 build minutes a month 51 | if you have a package in your project dependencies that has a high 52 | turnover of releases, like Gatsby, then each time there's a release 53 | Renovate will make a PR and the Netlify integration will kick off a 54 | build with the updated dependency. 55 | 56 | This is when things can start to break down a touch, say you have 57 | several projects all of which have Prettier installed along with 58 | Gatsby and another popular JS lib with high release turnover. If they 59 | all release on the same day for the many projects you have then say 60 | goodbye to the 300 build minutes you had with Netlify, Vercel will 61 | stop any builds being processed for what I've seen at four hours at a 62 | time when this happens as well. 63 | 64 | Renovate will try again when there's a new release, Gatsby can release 65 | many many times in one day, so if you have waited patiently through 66 | your four hours cut off to push another change and there's another 67 | release from Gatsby then you're back where you started as the Vercel 68 | integration will start getting hammered again by the Renovate bot 69 | being helpful and making PRs for you. 70 | 71 | ## Config 72 | 73 | "Why don't you configure it properly Scott?" You could avoid all this 74 | if you took the time to configure your `renovate.json` correctly. 75 | 76 | I love no a friction process, the thing with Renovate is it comes with 77 | a base configuration so there's no need to spend any time when you're 78 | first setting up your project to do that as well, just get on with 79 | what you're doing and let Renovate do it's thing in the background. 80 | 81 | Before I knew it though I had 30+ projects all with Renovate 82 | configured to ping a PR on all those projects and hammer my build 83 | queue for Vercel and Netlify any time there was a new release. 84 | 85 | ## Lessons learned 86 | 87 | I changed the default on Renovate to only be enabled on selected 88 | projects and not all by default. 89 | 90 | It was an incredible PITA (Pain in the Arse) to remove the Renovate 91 | config from each project. 92 | 93 | Using Renovate may sound like a good idea, everything is kept current 94 | and secure and you always have some PRs to review on GitHub. 95 | 96 | But if you have a lot of projects with a dependency that has high 97 | release rates or that you use in every project (Gatsby, Prettier) then 98 | when update time comes there's a lot of 'busy work' involved. 99 | 100 | 101 | 102 | [jamie barton]: https://twitter.com/notrab 103 | [navigation bar with graphcms]: 104 | https://github.com/spences10/gatsby-using-graphcms 105 | -------------------------------------------------------------------------------- /posts/2020/04/30/large-md-assets-to-cdn/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2020-04-30 3 | title: Moving Large Markdown Assets to a CDN 4 | tags: ['information', 'markdown'] 5 | private: false 6 | --- 7 | 8 | I've spent a while today trying to bring down the size of this 9 | project, I have several posts that are particularly large so I wanted 10 | to work out a way to reduce that. 11 | 12 | I'm an Ubuntu user and wanted to see if there was a way I could 13 | identify the larger files in the project. 14 | 15 | I found [this SO question] which details using the `du` command ([Disk 16 | Usage]) which I used to list out the folder sizes. I put the following 17 | command into my terminal: 18 | 19 | ```bash 20 | du --max-depth=7 /home/scott/repos/thelocalhost/posts/ | sort -n 21 | ``` 22 | 23 | It gave a similar output to this: 24 | 25 | ``` 26 | 592 /thelocalhost/posts/2017/01/04/twitter-mctwitbot 27 | 2412 /thelocalhost/posts/2017/01/28/twitter-bot-bootstrap 28 | 38708 /thelocalhost/posts/2018/12/24/wsl-bootstrap-2019 29 | ``` 30 | 31 | The output was a bit noisier that what I've put here actually, lot's 32 | of output, but it helped identify large assets in folders. That 33 | `wsl-bootstrap-2019` folder is nearly 40mb in size! 😱 34 | 35 | ## Markdown file structure 36 | 37 | I have become quite particular about my Markdown as of late and like 38 | to [structure things in a certain] way. I started to do this with the 39 | images and gifs that are in here as well. 40 | 41 | So, as an example this: 42 | 43 | ```markdown 44 | ![twitter logo](./twitter-bird.png) 45 | 46 | I got to doing this from finding it on [GitHub](https://github.com) I 47 | think I was looking for the Twitter icon in bootstrap whilst 48 | working... 49 | ``` 50 | 51 | Will become this: 52 | 53 | ```markdown 54 | ![twitter logo] 55 | 56 | I got to doing this from finding it on [GitHub] I think I was looking 57 | for the Twitter icon in bootstrap whilst working... 58 | 59 | 60 | 61 | [github]: https://github.com 62 | 63 | 64 | 65 | [twitter logo]: ./twitter-bird.png 66 | ``` 67 | 68 | It looks like the second option here takes more space but the links at 69 | the bottom of the document aren't visible and it makes the writing 70 | experience a lot easier to parse and manage when there are a lot of 71 | links and assets in the document. 72 | 73 | ## Cool story bro 74 | 75 | So I'm putting this here to document what I did, the assets in the 76 | large folder I mentioned earlier have now been removed and added to 77 | the Now CDN in their own folder. 78 | 79 | So now at the end of each document, rather than have a load of local 80 | files in the same folder they can all be references to the CDN. 81 | 82 | How do I add them to a CDN? I make a folder with the same(ish) folder 83 | structure then reference the CDN in place of the local images: 84 | 85 | ```text 86 | images-on-now-sh/ 87 | ├─ 2020/ 88 | ├── this-post-im-talking-about/ 89 | │ ├─ image1.png 90 | │ ├─ image2.png 91 | │ └─ image3.png 92 | ``` 93 | 94 | The whole reason I did this was so that if I wanted to I could run all 95 | these through a service like [Images.weserv.nl] where I could add the 96 | URL to their service like so: 97 | 98 | ```text 99 | [image1]: //images.weserv.nl/?url=https://images-on-now-sh/2020/this-post-im-talking-about/image1.png&w=300&h=300 100 | ``` 101 | 102 | I've not done that as yet, I have got a 25% faster build time for the 103 | site though. 104 | 105 | ## What CDN? 106 | 107 | The CDN I talk about is Vercel's Now platform, which I think in time 108 | is going to be called just Vercel, as the Now bot that used to look 109 | after your GitHub deploys is now called Vercel so they may be 110 | consolidating everything into _just_ Vercel. 111 | 112 | I loaded the assets to the Vercel CDN with the Now CLI, so in the 113 | folder that contains the assets do a `now` or `now --prod` to push the 114 | assets to the Vercel CDN. 115 | 116 | Any time I now have a post with a lot of assets images I'm not going 117 | to feel that bad about adding them. I have however stopped doing this 118 | so much and instead try to provide a video detailing something with 119 | accompanying copy. 120 | 121 | 122 | 123 | [this so question]: 124 | https://serverfault.com/questions/200949/how-can-i-find-the-biggest-directories-in-unix-ubuntu 125 | [structure things in a certain]: 126 | https://thelocalhost.io/2020/04/18/add-tracking-links-to-your-markdown/#the-other-problem-for-me-anyway- 127 | [disk usage]: https://ss64.com/bash/du.html 128 | [images.weserv.nl]: https://images.weserv.nl/docs/#how-it-works 129 | 130 | 131 | -------------------------------------------------------------------------------- /posts/2020/05/02/css-variables-dark-mode/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2020-05-02 3 | title: CSS Variables Fallback 4 | tags: ['information', 'css'] 5 | private: false 6 | --- 7 | 8 | I used CSS variables to make a theme switch, light and dark, I've done 9 | this [in the past] using styled-components but not attempted it via 10 | the CSS variables route. 11 | 12 | With styled-components you defined your colour schemes or themes in a 13 | `theme` object then use the styled-components `ThemProvider` to switch 14 | between the two high up in the component tree. 15 | 16 | This time round I used a React hook to switch the theme and used CSS 17 | variables for a light and dark theme. 18 | 19 | I got a bit carried away and used variables for lot's of other things 20 | besides a simple colour, I used it for gradients and a box shadow, 21 | here's the light side: 22 | 23 | ```css 24 | body[data-theme='light'] { 25 | --colour-background: #f7fafc; 26 | --colour-on-background: #1a202c; 27 | --box-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px 28 | rgba(0, 0, 0, 0.05); 29 | --box-shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 30 | 10px -5px rgba(0, 0, 0, 0.04); 31 | --title-gradient: linear-gradient(#9966cc, #663399); 32 | --qrt-turn-gradient: linear-gradient(0.25turn, #9966cc, #663399); 33 | } 34 | ``` 35 | 36 | This is mixed in with a design system approach I've adapted from how 37 | Tailwind is set out. 38 | 39 | So that CSS will be in a CSS-in-JS style and in this instance is 40 | living with the global styles of the project. They are defined in a JS 41 | theme object, and exported, like this: 42 | 43 | ```js 44 | export const GlobalStyle = createGlobalStyle` 45 | body[data-theme="light"] { 46 | --colour-background: ${({ theme }) => theme.colours.grey[100]}; 47 | --colour-on-background: ${({ theme }) => theme.colours.grey[900]}; 48 | } 49 | ... 50 | ` 51 | ``` 52 | 53 | I was using the CSS gradient like this, thinking that : 54 | 55 | ```css 56 | background: var(--title-gradient); 57 | -webkit-background-clip: text; 58 | background-clip: text; 59 | -webkit-text-fill-color: transparent; 60 | ``` 61 | 62 | I was quite happy and feeling kinda smug with myself that I could 63 | abstract away those gradients and box shadows. Then things started to 64 | get a bit janky on the first render and I couldn't work out what I had 65 | done wrong. 66 | 67 | 68 | 69 | I was getting an awful flash of unstyled content, well I say unstyled 70 | content, it wasn't actually unstyled as the text was transparent which 71 | was part of the styles, it's just the gradient wasn't being applied. 72 | 73 | So, go back to how it was originally, ok that worked: 74 | 75 | ```css 76 | background: linear-gradient(#9966cc, #663399); 77 | -webkit-background-clip: text; 78 | background-clip: text; 79 | -webkit-text-fill-color: transparent; 80 | ``` 81 | 82 | I found that if I didn't use the variable then it rendered fine, but I 83 | needed to use the variable or no theme! 84 | 85 | So I was searching for a fallback solution but couldn't find anything 86 | and it wasn't until I found [this article] that I realised that I was 87 | adding the fallback in the wrong place. 88 | 89 | ```css 90 | background: linear-gradient( 91 | var( 92 | --title-gradient-from, 93 | $ {({theme}) => theme.colours.primary[200]} 94 | ), 95 | var( 96 | --title-gradient-to, 97 | $ {({theme}) => theme.colours.primary[500]} 98 | ) 99 | ); 100 | -webkit-background-clip: text; 101 | background-clip: text; 102 | -webkit-text-fill-color: transparent; 103 | ``` 104 | 105 | This drawback here is that I have had to put in the default colour 106 | scheme fallback, which means if the user has the dark theme set then 107 | they're going to have the light theme flash first. 108 | 109 | 110 | 111 | [in the past]: https://thelocalhost.io/2018/09/08/react-context-api/ 112 | [this article]: 113 | https://medium.com/fbdevclagos/how-to-leverage-styled-components-and-css-variables-to-build-truly-reusable-components-in-react-4bbf50467666 114 | -------------------------------------------------------------------------------- /posts/2020/05/02/moving-from-now-to-netlify/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2020-05-02 3 | title: Moving from Now to Netlify then back to Now 4 | tags: ['netlify', 'information'] 5 | private: false 6 | --- 7 | 8 | I am a massive fan of both Vercel's [Now.sh] platform and the 9 | [Netlify] platform. 10 | 11 | This post has been in my drafts since the beginning of March 2019. At 12 | that time it was titled **'Moving from Now to Netlify'** and it was 13 | mostly me being salty about the configuration of the Now service. 14 | 15 | At that time I had fallen for Netlify and was swooning over it's super 16 | simple deployments and domain management. That along with it's awesome 17 | caching making your Lighthouse audits something you'd boast about on 18 | Twitter. 19 | 20 | Yeah, those people are the _worst_! 21 | 22 | 23 | 24 | Ha! Yes, guilty! 25 | 26 | **Anyhoo!** Like the fickle Twitter driven web developer I am, 27 | switching technology every week is expected! 😂 28 | 29 | So now I'm back in the [Now.sh] camp. **Why?** I could say it's 30 | because I prefer the new name change from ZEIT to Vercel. 31 | 32 | It's not, I could say that it's because Vercel has massively upped 33 | their game in the last two years. They have but it's not that either. 34 | 35 | [Netlify] is an awesome platform and I love working with it, I'd 36 | absolutely recommend it to anyone. 37 | 38 | I like to the convenience of being able to switch at between them, so 39 | if I decide I want to go with x platform I can up and move relatively 40 | quickly [with no downtime]. 41 | 42 | ## Vercel's Now.sh platform is also a CDN 43 | 44 | I'm going through all the assets in posts on here and adding them with 45 | the Now CLI so I can use a link to them directly, or through a service 46 | like [Images.weserv.nl] for further optimisations. 47 | 48 | I know that Gatsby will optimise images on the fly for best sizes I'm 49 | doing this as a learning exercise as much as was to improve 50 | performance. 51 | 52 | I'll probably be back on Netlify or the next new hotness by the time 53 | you're reading this! 54 | 55 | ## What I'v learned 56 | 57 | Try to keep things with as little lock in as possible so you can truly 58 | utilise the content mesh. 59 | 60 | The irony here is that I've completely flip flopped from one back to 61 | the other but as I have my domains with Namecheap all I need to do is 62 | change the DNS configuration and we're done! 63 | 64 | In the past I purchased some domains with Vercel but if I wanted to 65 | move then I'd need to migrate the domain or at lease configure the DNS 66 | with the Now CLI. 67 | 68 | Domain management with Vercel Now CLI is something that I have always 69 | been _ok_ managing. I did find the Netlify console just as 70 | straightforward to use but if you find the terminal a bit daunting for 71 | something like this then Vercel now have a [DNS integration] that 72 | makes it a lot more visual. 73 | 74 | 75 | 76 | [now.sh]: https://now.sh 77 | [netlify]: https://www.netlify.com/ 78 | [greenkeeper.io]: https://greenkeeper.io 79 | [images.weserv.nl]: https://images.weserv.nl/docs/quick-reference.html 80 | [with no downtime]: 81 | https://vercel.com/guides/zero-downtime-domain-migration 82 | [dns integration]: https://vercel.com/integrations/dns 83 | -------------------------------------------------------------------------------- /posts/2020/05/04/patching-packages/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2020-05-04 3 | title: Patching Packages with patch-package 4 | tags: ['netlify', 'information'] 5 | private: false 6 | --- 7 | 8 | I found an opportunity to improve the npm package for the 9 | _`Victor Mono`_ font I like to use here and in my text editor (much to 10 | people horror when they see it)! 11 | 12 | It was a simple fix to add `font-display: swap;` to the css file in 13 | the dist package. 14 | 15 | The maintainer was super responsive and added the change straight away 16 | which was cool, that doesn't mean that the changes are going to be 17 | packaged up and released that quickly. 18 | 19 | Looking at the [releases] it could be a while before this gets 20 | published to npm so I decided to give patch-package a try. 21 | 22 | ## Video on patch-package 23 | 24 | [Ben Awad] had a great video on how to use it with an example, check 25 | it out here: 26 | 27 | 28 | 29 | ## Install 30 | 31 | I'm using Yarn so I installed both patch-package and 32 | postinstall-postinstall: 33 | 34 | ```bash 35 | yarn add -D patch-package postinstall-postinstall 36 | ``` 37 | 38 | ## Make the change 39 | 40 | In this case I want to change my `victormono` package, so, I can find 41 | it in the `node_modules`. 42 | 43 | Check the `package.json` for the `"main"` file, Victor Mono is quite a 44 | simple project so there's just the one `dist/index.css` I can take the 45 | changes made [to the GitHub project] and add them to my version of the 46 | package. 47 | 48 | ## Patch it 49 | 50 | Now I have the change locally on my machine I want to keep them 51 | around, if I push what I have currently a build process will install 52 | from the registry which doesn't have the fix. 53 | 54 | I need to tell patch-package what package I want to patch: 55 | 56 | ```bash 57 | yarn patch-package victormono 58 | ``` 59 | 60 | Then patch-package will create a `patches` folder in the root of my 61 | project where I can inspect the patch changes. 62 | 63 | ```bash 64 | this-project/ 65 | └─ patches/ 66 | └─ victormono+1.3.1.patch 67 | ``` 68 | 69 | ## View the patch 70 | 71 | Opening the `.patch` file displays the changes made: 72 | 73 | ```git 74 | diff --git a/node_modules/victormono/dist/index.css b/node_modules/victormono/dist/index.css 75 | index 82c84f1..9e1131f 100644 76 | --- a/node_modules/victormono/dist/index.css 77 | +++ b/node_modules/victormono/dist/index.css 78 | @@ -4,6 +4,7 @@ 79 | url("woff/VictorMono-Regular.woff") format("woff"); 80 | font-weight: 400; 81 | font-style: normal; 82 | + font-display: swap; 83 | } 84 | 85 | @font-face { 86 | @@ -12,6 +13,7 @@ 87 | url("woff/VictorMono-Italic.woff") format("woff"); 88 | font-weight: 400; 89 | font-style: italic; 90 | + font-display: swap; 91 | } 92 | 93 | @font-face { 94 | @@ -20,6 +22,7 @@ 95 | url("woff/VictorMono-Bold.woff") format("woff"); 96 | font-weight: 700; 97 | font-style: normal; 98 | + font-display: swap; 99 | } 100 | 101 | @font-face { 102 | @@ -28,4 +31,5 @@ 103 | url("woff/VictorMono-BoldItalic.woff") format("woff"); 104 | font-weight: 700; 105 | font-style: italic; 106 | + font-display: swap; 107 | } 108 | \ No newline at end of file 109 | ``` 110 | 111 | > If you have Prettier installed and set to format on save use 112 | > Ctrl+Shit+p and select `File: Save without Formatting` when changing 113 | > other packages 114 | 115 | Saving without formatting on the package you want to change will make 116 | the `.patch` file less noisy only including the relevant changes. 117 | 118 | ## Use postinstall 119 | 120 | I've added postinstall-postinstall to run patch-package, this will 121 | mean that the patch file created by patch-package gets applied after 122 | the project is built. 123 | 124 | ```json 125 | "scripts": { 126 | "postinstall": "patch-package" 127 | }, 128 | ``` 129 | 130 | I can now publish my project with the patches until the Victor Mono 131 | npm package changes. At that time I will get a prompt to tell me the 132 | package has changed probably via a failed build, then I can either 133 | change my patch or remove it completely. 134 | 135 | 136 | 137 | [github issue]: https://github.com/rubjo/victor-mono/issues/77 138 | [releases]: https://github.com/rubjo/victor-mono/releases 139 | [ben awad]: https://www.youtube.com/channel/UC-8QAzbLcRglXeN_MY9blyw 140 | [to the github project]: 141 | https://github.com/rubjo/victor-mono/commit/f6a7ed793d37a281674d794b630ce16a1303899e 142 | -------------------------------------------------------------------------------- /posts/2020/05/09/css-resources/circleImages.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/05/09/css-resources/circleImages.jpg -------------------------------------------------------------------------------- /posts/2020/05/09/css-resources/desaturatingImages.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/2020/05/09/css-resources/desaturatingImages.jpg -------------------------------------------------------------------------------- /posts/2020/05/09/css-resources/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2020-05-09 3 | title: CSS Resources From Around the Web 4 | tags: ['css', 'resource'] 5 | private: false 6 | --- 7 | 8 | This is a collection of some handy snippets and resources I collected 9 | which I'm going to be documenting here, it's probably going to be a 10 | mess but it mainly for my reference. 11 | 12 | Big thanks to Steve Schoger and Adam Wathan 🙏 13 | 14 | Check out Refactoring UI and the Refactoring UI YouTube channel for 15 | more hot tips 🔥 16 | 17 | ## Debugging 18 | 19 | From **Adam Wathan:** 20 | 21 | > Ever run into annoying CSS layout bugs that are hard to 22 | > troubleshoot? (WHY IS THERE A HORIZONTAL SCROLLBAR WHERE IS THIS 23 | > COMING FROM?!?) 24 | 25 | > Throw this style into your dev tools to see the boundaries of every 26 | > element without affecting the layout: 27 | 28 | ```css 29 | * { 30 | outline: 1px solid red !important; 31 | } 32 | ``` 33 | 34 | 35 | 36 | ## Images 37 | 38 | From **Steve Schoger:** 39 | 40 | > Working with images that clash with each other? Try desaturating 41 | > them to greyscale or colourising them all with a single colour to 42 | > make them a little more cohesive. 43 | 44 | ![desaturating images] 45 | 46 | > Also, containing photos in circles - Great way to make a bad photo 47 | > look good 48 | 49 | ![circle images] 50 | 51 | 52 | 53 | ## Gradients 54 | 55 | There is a lot of content out there for this but I have found some 56 | quite nice ones. 57 | 58 | Gradient maker: [cssgradient.io/gradient-backgrounds] 59 | 60 | Nice Gradient Swatches: [gradientmagic.com] 61 | 62 | Animated gradients, via Chris Biscardi, example: [animated gradients 63 | Codesandbox] 64 | 65 | 66 | 67 | ## Colours 68 | 69 | Colour contrast picker, this will give you a selection of colours with 70 | a 4.5:1 ratio: [tanaguru contrast finder] 71 | 72 | Leet speak and colours: [bada55.io] 73 | 74 | For getting shades of a colour I lke to use 0to255 : [0to255.com] 75 | 76 | Colour Space has a nice UI for creating colour pallets: 77 | [mycolor.space] 78 | 79 | Adobe Colour Wheel has good presets for picking colour pallets: 80 | [color.adobe.com] 81 | 82 | Automatic UI Colour Palette Generator: [palx.jxnblk.com] 83 | 84 | Name a colour from hex: [color-hex.com] 85 | 86 | Hello Colour: [jxnblk.com/hello-color] 87 | 88 | Beautiful colour scales Colour Box: [colorbox.io] 89 | 90 | Colour Scale: [hihayk.github.io/scale] 91 | 92 | React colour tools: [react-color-tools.surge.sh] 93 | 94 | ## Internal browser colour names 95 | 96 | I've asked this question a couple of times before, **"is there a way 97 | to list the internal browser colours?"** 98 | 99 | 100 | 101 | The last time I asked [Mathias Bynens] answered! 102 | 103 | 104 | 105 | If you want the list go to the [the CSS3 spec] and run this snippet in 106 | the dev console: 107 | 108 | ```js 109 | ;[ 110 | ...document.querySelectorAll( 111 | '.named-color-table [id^="valdef-color-"]' 112 | ), 113 | ].map(element => element.textContent) 114 | ``` 115 | 116 | ## Neumorphism 117 | 118 | Neumorphism.io is a cool tool for generating your neumorphism boxes: 119 | [neumorphism.io] 120 | 121 | ## Effects 122 | 123 | Glitch Text Effect: [css-tricks.com/glitch-effect-text-images-svg] 124 | 125 | Fancy Border Radius: [9elements.github.io/fancy-border-radius] 126 | 127 | ## Numbers in CSS 128 | 129 | Width for elements changing when using numbers? Check: 130 | [`font-variant-numeric`] 131 | 132 | I asked and the community of course responded! 133 | 134 | 135 | 136 | I also found the original tweet I saw from Wes Bos back in 2017! 137 | 138 | 139 | 140 | ## CSS Grid 141 | 142 | CSS Grid has a good UI for building CSS Grid Layouts: 143 | [layoutit.com/build] 144 | 145 | ## New CSS Logical Properties 146 | 147 | New CSS Logical Properties!: [medium post] 148 | 149 | 150 | 151 | [cssgradient.io/gradient-backgrounds]: 152 | https://cssgradient.io/gradient-backgrounds/ 153 | [gradientmagic.com]: https://www.gradientmagic.com/# 154 | [https://cssgradient.io]: https://cssgradient.io/ 155 | [neumorphism.io]: https://neumorphism.io/#55b9f3 156 | [medium post]: 157 | https://medium.com/@elad/new-css-logical-properties-bc6945311ce7 158 | [css-tricks.com/glitch-effect-text-images-svg]: 159 | https://css-tricks.com/glitch-effect-text-images-svg/ 160 | [`font-variant-numeric`]: 161 | https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-numeric 162 | [mycolor.space]: https://mycolor.space/?hex=%23663399&sub=1 163 | [color.adobe.com]: https://color.adobe.com 164 | [palx.jxnblk.com]: https://palx.jxnblk.com/ 165 | [bada55.io]: http://bada55.io/ 166 | [0to255.com]: https://www.0to255.com/ 167 | [color-hex.com]: https://www.color-hex.com/ 168 | [jxnblk.com/hello-color]: https://jxnblk.com/hello-color 169 | [colorbox.io]: https://www.colorbox.io/ 170 | [hihayk.github.io/scale]: https://hihayk.github.io/scale 171 | [eggradients.com]: https://www.eggradients.com/ 172 | [react-color-tools.surge.sh]: https://react-color-tools.surge.sh/ 173 | [worldvectorlogo.com]: https://worldvectorlogo.com/search/GraphQL 174 | [layoutit.com/build]: https://www.layoutit.com/build 175 | [desaturating images]: ./desaturatingImages.jpg 176 | [circle images]: ./circleImages.jpg 177 | [9elements.github.io/fancy-border-radius]: 178 | https://9elements.github.io/fancy-border-radius 179 | [mathias bynens]: https://twitter.com/mathias 180 | [the css3 spec]: https://drafts.csswg.org/css-color/#named-colors 181 | [tanaguru contrast finder]: https://contrast-finder.tanaguru.com/ 182 | [animated gradients codesandbox]: 183 | https://codesandbox.io/s/muddy-sun-gp0el 184 | -------------------------------------------------------------------------------- /posts/2020/05/09/vscode-snippets/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2020-05-09 3 | title: VS Code Tips and Snippets 4 | tags: ['information', 'learning', 'guide'] 5 | private: true 6 | --- 7 | 8 | Use the same frontmatter block all the time for your blog posts? 9 | 10 | I do, so I've created a VS Code snippet to pre-populate the block with 11 | some default tags and today's date. 12 | 13 | To create it I opened my global VS Code snippets file, `Ctrl+Shift+p` 14 | then search `snippets` and select "Preferences: Configure User 15 | Snippets" I have all my snippets in a global file. 16 | 17 | ```json 18 | "frontmatterBlock": { 19 | "prefix": "fmb", 20 | "body": [ 21 | "---", 22 | "date: $CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE", 23 | "title: $1", 24 | "tags: ['information', 'learning', 'guide']", 25 | "private: true", 26 | "---" 27 | ], 28 | "description": "frontmatter block for frontmattering" 29 | }, 30 | ``` 31 | 32 | I've named the property `frontmatterBlock` with the prefix of "fmb" 33 | this is what I'll type into VS Code to activate the VS Code 34 | intellisense then tab to complete the operation. 35 | 36 | The `$1` is where the cursor goes to when the snippet is added, you 37 | can place these where you want to tab to once the snippet has been 38 | added. 39 | 40 | So, if I wanted to not have the default tags that are currently there 41 | I can replace them like this: 42 | 43 | ```json {7} 44 | "frontmatterBlock": { 45 | "prefix": "fmb", 46 | "body": [ 47 | "---", 48 | "date: $CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE", 49 | "title: $1", 50 | "tags: ['$2', '$3', '$4']", 51 | "private: true", 52 | "---" 53 | ], 54 | "description": "frontmatter block for frontmattering" 55 | }, 56 | ``` 57 | 58 | Now after tab completing the snippet I can tab through those sections 59 | in the snippet to add the details. 60 | -------------------------------------------------------------------------------- /posts/private/creat-a-html-auth-form/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2020-12-31 3 | title: Create a Simple Auth Form in HTML, CSS and JavaScript 4 | tags: ['learning', 'guide'] 5 | private: true 6 | --- 7 | 8 | I was asked to create a simple auth from at work, this tweet 9 | immediately sprang to mind. 10 | 11 | 12 | 13 | 14 | 15 | All it needed to do was hit and endpoint and redirect to a link. 16 | 17 | ## Scaffold out the form 18 | 19 | ## Style 20 | 21 | ## JavaScript 22 | 23 | ## Thanks for reading 🙏 24 | 25 | That’s all folks! If there is anything I have missed, or if there is a 26 | better way to do something then please let me know. 27 | 28 | Follow me on [Twitter] or [Ask Me Anything] on GitHub. 29 | 30 | 31 | 32 | [twitter]: https://twitter.com/spences10 33 | [ask me anything]: https://github.com/spences10/ama 34 | -------------------------------------------------------------------------------- /posts/private/creat-a-html-auth-form/like-a-psychopath.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/posts/private/creat-a-html-auth-form/like-a-psychopath.png -------------------------------------------------------------------------------- /posts/private/create-a-video-overlay-with-hooks/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2020-12-31 3 | title: Create a Video Overlay with Hooks 4 | tags: ['information', 'learning', 'guide', 'hooks', 'react'] 5 | private: true 6 | --- 7 | 8 | Create a Video overlay with React hooks 9 | 10 | ```js 11 | // useModal.js 12 | import { useState } from 'react' 13 | 14 | export const useModal = () => { 15 | const [isShowing, setIsShowing] = useState(false) 16 | 17 | const toggle = () => { 18 | setIsShowing(!isShowing) 19 | } 20 | 21 | return { 22 | isShowing, 23 | toggle, 24 | } 25 | } 26 | ``` 27 | 28 | ```js 29 | // VideoPlayer.js 30 | import React from 'react' 31 | import ReactPlayer from 'react-player' 32 | 33 | export const VideoPlayer = props => { 34 | return ( 35 | 48 | ) 49 | } 50 | ``` 51 | 52 | ```js 53 | // VideoModal.js 54 | import React from 'react' 55 | import ReactDOM from 'react-dom' 56 | import styled from 'styled-components' 57 | import closePrimary from '../../static/buttonClose.svg' 58 | import { VideoPlayer } from './VideoPlayer' 59 | 60 | const ModalOverlay = styled.div` 61 | position: fixed; 62 | top: 0; 63 | left: 0; 64 | width: 100vw; 65 | height: 100vh; 66 | background-color: darkgrey; 67 | opacity: 0.5; 68 | ` 69 | 70 | const ModalWrapper = styled.div` 71 | position: fixed; 72 | top: 0; 73 | left: 0; 74 | outline: 0; 75 | position: fixed; 76 | top: 10vh; 77 | bottom: 10vh; 78 | left: 10vh; 79 | right: 10vh; 80 | display: flex; 81 | ` 82 | 83 | const ModalHeader = styled.div` 84 | position: fixed; 85 | top: 20px; 86 | right: 20px; 87 | padding: 1.5rem; 88 | z-index: 1; 89 | ` 90 | 91 | const Modal = styled.div` 92 | background: ${({ theme }) => theme.primary}; 93 | position: relative; 94 | border-radius: 3px; 95 | display: flex; 96 | flex-direction: column; 97 | flex: 1; 98 | ` 99 | 100 | const CloseButton = styled.div` 101 | padding: 30px; 102 | border-radius: 50%; 103 | margin: -1rem -1rem -1rem auto; 104 | cursor: pointer; 105 | background-repeat: no-repeat; 106 | background-image: url(${closePrimary}); 107 | ` 108 | 109 | const PlayerWrapper = styled.div` 110 | position: relative; 111 | flex: 1; 112 | padding: 50px 0; 113 | ` 114 | 115 | const PlayerSizer = styled.div` 116 | width: 0; 117 | height: 100%; 118 | padding-right: 82%; 119 | margin: 0 auto; 120 | ` 121 | 122 | export const VideoModal = ({ isShowing, hide }) => 123 | isShowing 124 | ? ReactDOM.createPortal( 125 | <> 126 | 127 | 133 | 134 | 135 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | , 149 | document.body 150 | ) 151 | : null 152 | ``` 153 | 154 | Then in the component: 155 | 156 | ```js 157 | import React from 'react' 158 | import { VideoModal } from '../components/VideoModal' 159 | import { useModal } from '../hooks/useModal' 160 | import styled from 'styled-components' 161 | import playSvg from '../../static/playIcon.svg' 162 | 163 | const Wrapper = styled.div` 164 | height: 100%; 165 | display: flex; 166 | align-items: center; 167 | justify-content: center; 168 | ` 169 | 170 | const PlayDiv = styled.div` 171 | /* margin: 0 auto; */ 172 | background-repeat: no-repeat; 173 | height: 50px; 174 | width: 50px; 175 | background-image: url(${playSvg}); 176 | ` 177 | 178 | export default () => { 179 | const { isShowing, toggle } = useModal() 180 | return ( 181 | <> 182 | 183 | 184 | {/* */} 185 | 186 | 187 | 188 | ) 189 | } 190 | ``` 191 | -------------------------------------------------------------------------------- /posts/private/fish-shell-introduction/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2020-12-31 3 | title: Fish Shell Introduction 4 | tags: ['information', 'learning'] 5 | private: true 6 | --- 7 | 8 | As a developer you spend a lot of time in the terminal so it's 9 | important to be happy and as productive as possible whilst you're in 10 | there. 11 | 12 | This is why I'm a big fan of the Fish Shell in particular. The Fish 13 | Shell is a user friendly shell with really handy features like 14 | auto-suggestions and tab completions that come preconfigured, no need 15 | to install additional plugins and mess around with config files. 16 | That's not to say Fish Shell isn't configurable, there are plugins 17 | available. 18 | 19 | ## Navigation 20 | 21 | Ok, let's look at a typical navigation example in bash, if you want to 22 | change directory, you have to enter `cd` followed by the directory 23 | name. In Fish you only need to type out the directory name. 24 | 25 | Similarly if you want to go back a directory in bash, you need to 26 | start with `cd` in Fish it's just a case of `../`. 27 | 28 | ```bash 29 | # change directories in bash 30 | cd Downloads 31 | cd ../ 32 | # change directories in fish 33 | Downloads/ 34 | ../ 35 | ``` 36 | 37 | ## Auto-suggestions 38 | 39 | Fish will suggest both directories and commands as you type away, you 40 | will see suggestions in grey which you can tab onto to select. 41 | 42 | If you want to go through you last `yarn` (or `npm`) commands, rather 43 | than (like in bash) arrow through all you previously entered commands 44 | (I know you can use `Ctr+r` in bash) or print out the history and look 45 | at that. 46 | 47 | In Fish if you start typing out your command, let's say `yarn` you can 48 | then arrow through all commands that have included `yarn` it doesn't 49 | even have to be the beginning of the command, if you have used a 50 | package and want to know what else you installed with it at the time 51 | you can use the package name then arrow though all command with that 52 | keyword in there. 53 | 54 | ## Tab Completions 55 | 56 | ## Aliases 57 | 58 | Aliases are where you're too lazy to keep typing in the full command 59 | again and again so you make a shorter one, for me I have aliased `git` 60 | to `g` in Fish, (I know, but that extra two characters over time is a 61 | lot). 62 | 63 | Aliases in shells like bash and zsh you need to open your config file 64 | and find a appropriate place to add you alias. In 65 | 66 | ## Install Fish shell 67 | 68 | Linux and Windows Subsystem Linux: 69 | 70 | ```bash 71 | sudo apt -y install fish 72 | ``` 73 | 74 | macOS: 75 | 76 | ```bash 77 | brew install fish 78 | curl -L https://get.oh-my.fish | fish 79 | sudo bash -c 'echo /usr/local/bin/fish >> /etc/shells' 80 | chsh -s /usr/local/bin/fish 81 | ``` 82 | 83 | ## Oh My Fish (OMF) 84 | 85 | [Oh My Fish] is touted as the Fishshell Framework but all I have used 86 | it for is the extensive themes available, once you have installed OMF 87 | you can list them out in the terminal with: `omf theme` 88 | 89 | There's previews available on the [OMF Themes Markdown doc]. 90 | 91 | To install OMF, in the terminal enter the following command: 92 | 93 | ```bash 94 | curl -L https://get.oh-my.fish | fish 95 | ``` 96 | 97 | An [extensive list] of packages available too 98 | 99 | ```bash 100 | omf describe brew 101 | ``` 102 | 103 | ```text 104 | Package: brew 105 | Description: Oh My Fish plugin to integrate Homebrew paths into shell. 106 | Repository: https://github.com/oh-my-fish/plugin-brew 107 | Maintainer: 108 | ``` 109 | 110 | 111 | 112 | [omf themes markdown doc]: 113 | https://github.com/oh-my-fish/oh-my-fish/blob/master/docs/Themes.md 114 | [extensive list]: 115 | https://github.com/oh-my-fish/packages-main/tree/master/packages 116 | [oh my fish]: https://github.com/oh-my-fish/oh-my-fish 117 | -------------------------------------------------------------------------------- /posts/private/javascript-snippets/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2019-05-27 3 | title: JavaScript snippets from around the web 4 | tags: ['information', 'learning', 'javascript', 'snippets'] 5 | private: true 6 | --- 7 | 8 | This is a dump of all the snippets I have collected over the last 18 9 | months or so, that I'm going to document here so it's probably going 10 | to be a mess but it's mainly for my reference so 😛 11 | 12 | ## Arrays 13 | 14 | Straight from Wes himself. 15 | 16 | 🔥 The Array `.some()` Method is super handy for checking if at least 17 | one item in an array meets what you are looking for 18 | 19 | ```js 20 | const user = { 21 | name: 'Scott', 22 | permissions: ['USER', 'CREATE_ITEM'], 23 | } 24 | 25 | // check if the user is either admin or can delete in item 26 | const canDelete = user.permissions.some(p => 27 | ['ADMIN', 'DELETE_ITEM'].includes(p) 28 | ) 29 | // canDelete is false 30 | 31 | // check if a user is either admin or can create in item 32 | const canCreate = user.permissions.some(p => 33 | ['ADMIN', 'CREATE_ITEM'].includes(p) 34 | ) 35 | // canDelete is true 36 | ``` 37 | 38 | On the same note `.every()` is great for checking every item in an 39 | array meets what you are looking for. 40 | 41 | ```js 42 | const people = [ 43 | { name: 'Scott', age: 42 }, 44 | { name: 'Sue', age: 26 }, 45 | { name: 'Orla', age: 9 }, 46 | ] 47 | 48 | const canEveryoneDrink = people.every(p => p.age >= 18) 49 | // false 50 | 51 | const canSomeoneDrink = people.some(p => p.age >= 18) 52 | // true 53 | 54 | const howManyDrinkers = people.filter(p => p.age >= 18).length 55 | // 2 56 | ``` 57 | 58 | ## Via Addy Osmani 59 | 60 | Get the unique values of an array in JS. Use ES2015 `Set()` and 61 | `...rest` to discard duplicate values. 62 | 63 | ```js 64 | const uniqueArray = arr => [...new Set(arr)] 65 | 66 | uniqueArray([1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 0, 0, 10, 10]) 67 | // Array(9) [ 1, 2, 3, 4, 5, 6, 7, 0, 10 ] 68 | uniqueArray([ 69 | 'London', 70 | 'Manchester', 71 | 'Cambridge', 72 | 'London', 73 | 'Greater London', 74 | 'London', 75 | 'Manchester', 76 | ]) 77 | // Array(4) [ "London", "Manchester", "Cambridge", "Greater London" ] 78 | ``` 79 | 80 | `Array.from()` accepts another `.map` arguments. Useful for calling 81 | each element of a created array. 82 | 83 | ```js 84 | const year = new Date().getFullYear() 85 | const totalYears = 5 86 | 87 | Array.from('web') 88 | // Array(3) [ "w", "e", "b" ] 89 | 90 | Array.from(Array(totalYears), (_, i) => year + i) 91 | // Array(5) [ 2019, 2020, 2021, 2022, 2023 ] 92 | 93 | Array.from({ length: totalYears }, (_, i) => year + i) 94 | // Array(5) [ 2019, 2020, 2021, 2022, 2023 ] 95 | ``` 96 | 97 | ## Async await 98 | 99 | ```js 100 | const getAsyncStuff = async name => { 101 | try { 102 | const response = await fetch( 103 | `https://api.github.com/users/${name}` 104 | ) 105 | return await response.json() 106 | } catch (err) { 107 | console.error(err) 108 | } 109 | } 110 | ``` 111 | 112 | 🔥 4 Ways to handle the double promise with fetch() and async+await 113 | 114 | ```js 115 | const url = 'https://api.github.com/users/spences10' 116 | 117 | async function go() { 118 | // 1. tac a promise onto the end 119 | const p1 = await fetch(url).then(data => data.json()) 120 | 121 | // 2. double 122 | const p2 = await (await fetch(url)).json() 123 | 124 | // 3. capture promise in a variable 125 | const data = await fetch(url) 126 | 127 | // then convert it on another line 128 | const p3 = await data.json() 129 | 130 | // 4. create a utility function 131 | const p4 = await getJSON(url) 132 | } 133 | 134 | // use ... spread to get all arguments 135 | function getJSON(...butter) { 136 | // then spread into the fetch function 137 | return fetch(...butter).then(data => data.json()) 138 | } 139 | 140 | go() 141 | ``` 142 | -------------------------------------------------------------------------------- /posts/private/preact-getting-started/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2020-12-31 3 | title: Getting started with Preact and the Preact CLI 4 | tags: ['learning', 'guide'] 5 | private: true 6 | --- 7 | 8 | For the past couple of weeks now I have been getting familiar with 9 | Preact and the Preact CLI. 10 | 11 | It's great, it's _similar_ to React 12 | 13 | ## The { h } isn't needed 14 | 15 | I was quite hung up on the `{ h }` import, I use the VSCode setting to 16 | organise the imports on save. 17 | 18 | ```json 19 | "editor.codeActionsOnSave": { 20 | "source.organizeImports": true 21 | }, 22 | ``` 23 | 24 | That stripped out the `{ h }` I was concerned that it would break but 25 | then found out it worked fine without it. 26 | 27 | > `preact-cli` automatically imports `h` for you in any files that 28 | > have JSX, so you can safely remove those imports. 29 | 30 | ## Local fonts added to the assets folder 31 | 32 | The way I got local fonts into the project was by creating a 33 | `fonts.css` file and importing that into the `template.html` file as a 34 | link `` 35 | 36 | ```css 37 | @font-face { 38 | font-family: 'My Local Font'; 39 | src: url('./MyLocalFont.ttf') format('truetype'); 40 | } 41 | ``` 42 | 43 | As I only have the `.ttf` font file that is all that I have imported. 44 | 45 | If you're using multiple font files then take a look at the [CSS 46 | Tricks post] on it. 47 | 48 | ```html 49 | 50 | 51 | 52 | 53 | <% preact.title %> 54 | 58 | 59 | 60 | 61 | <% preact.headEnd %> 62 | 63 | 64 | <% preact.bodyEnd %> 65 | 66 | 67 | ``` 68 | 69 | This can also do this with Google fonts, something like this: 70 | 71 | ```html 72 | 73 | 74 | 75 | 76 | <% preact.title %> 77 | 81 | 82 | 83 | 87 | <% preact.headEnd %> 88 | 89 | 90 | <% preact.bodyEnd %> 91 | 92 | 93 | ``` 94 | 95 | 96 | 97 | [css tricks post]: 98 | https://css-tricks.com/snippets/css/using-font-face/ 99 | -------------------------------------------------------------------------------- /posts/private/styled-components-resources/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2020-05-11 3 | title: Styled Components Resources 4 | tags: ['styling', 'resource', 'styled-components'] 5 | private: true 6 | --- 7 | 8 | A curated list of hints and tips for using styled-components. 9 | 10 | ## Breakpoints 11 | 12 | The first way I found how to do `@media` queries in styled-components 13 | was documented on a Gist. 14 | 15 | This is a lift and drop from an old project: 16 | 17 | ```js 18 | const sizes = { 19 | monitor: 1800, 20 | giant: 1500, 21 | desktop: 992, 22 | tablet: 768, 23 | phone: 376, 24 | } 25 | 26 | // iterate through the sizes and create a media template 27 | export const media = Object.keys(sizes).reduce( 28 | (accumulator, label) => { 29 | // use em in breakpoints to work properly cross-browser and support users 30 | // changing their browsers font-size: https://zellwk.com/blog/media-query-units/ 31 | const emSize = sizes[label] / 16 32 | accumulator[label] = (...args) => css` 33 | @media (max-width: ${emSize}em) { 34 | ${css(...args)}; 35 | } 36 | ` 37 | return accumulator 38 | }, 39 | {} 40 | ) 41 | ``` 42 | 43 | Then to use it in the project: 44 | 45 | ```js 46 | const PageContainer = styled.div` 47 | ${media.monitor` 48 | background: goldenrod; 49 | `}; 50 | ${media.giant` 51 | background: goldenrod; 52 | `}; 53 | ${media.desktop` 54 | background: dodgerblue; 55 | `}; 56 | ${media.tablet` 57 | background: mediumseagreen; 58 | `}; 59 | ${media.phone` 60 | background: palevioletred; 61 | `}; 62 | ` 63 | ``` 64 | -------------------------------------------------------------------------------- /posts/private/track-custom-events-with-google-analytics/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2019-09-16 3 | title: Track Custom Events With Google Analytics 4 | tags: ['information', 'learning', 'guide', 'hooks', 'react'] 5 | private: true 6 | --- 7 | 8 | Do you use Google Analytics (GA) for any of your sites? 9 | 10 | I've used it in the past and it gives quite good information about 11 | 12 | Want to track what users of your site are clicking and navigating to? 13 | 14 | Let's talk about Google Analytics, what is it used for 15 | 16 | Tracking Events 17 | 18 | Privacy Policy 19 | 20 | Ambulance Chasers 21 | 22 | We're going to use the React context API 23 | 24 | ```js 25 | import React, { useContext, useEffect } from 'react' 26 | 27 | const AnalyticsContext = React.createContext({}) 28 | 29 | export const AnalyticsProvider = ({ children }) => { 30 | useEffect(() => { 31 | if (typeof window.ga === 'undefined') { 32 | window.ga = (x, y) => { 33 | console.log(`I'm a fake GA`, x, y) 34 | } 35 | } 36 | }, []) 37 | 38 | const events = { 39 | logButtonPress: e => { 40 | window.ga('send', { 41 | hitType: 'event', 42 | eventCategory: 'buttonPress', 43 | eventAction: 'click', 44 | eventLabel: e.target.innerText, 45 | }) 46 | }, 47 | logSocial: socialMediaPlatform => { 48 | window.ga('send', { 49 | hitType: 'event', 50 | eventCategory: 'socialShareClicks', 51 | eventAction: 'click', 52 | eventLabel: socialMediaPlatform, 53 | }) 54 | }, 55 | logNavigation: navItem => { 56 | window.ga('send', { 57 | hitType: 'event', 58 | eventCategory: 'navigationClicks', 59 | eventAction: 'click', 60 | eventLabel: navItem, 61 | }) 62 | }, 63 | } 64 | return ( 65 | 66 | {children} 67 | 68 | ) 69 | } 70 | 71 | export const useAnalytics = () => { 72 | return useContext(AnalyticsContext) 73 | } 74 | ``` 75 | 76 | As high up the component tree add the provider. 77 | 78 | ```js 79 | import { AnalyticsProvider } from '../components/GAEventTracking' 80 | ``` 81 | 82 | Then use in the areas you Want 83 | 84 | ```js 85 | export const ButtonComponent = props => { 86 | const analytics = useAnalytics() 87 | return ( 88 | 91 | ) 92 | } 93 | ``` 94 | -------------------------------------------------------------------------------- /posts/private/why-is-anything-intimidating/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2019-09-01 3 | title: Why is anything intimidating? 4 | tags: ['ramble', '!dev', 'habits'] 5 | excerpt: '' 6 | private: true 7 | --- 8 | 9 | Stand back everyone, I'm doing pontification! I've had a couple 10 | conversations with my new found developer buddies about fitness, more 11 | along the lines of gym going and nutrition actually. 12 | 13 | One friend in particular Danielle Ormshaw asked why is going to the 14 | gym so intimidating? 15 | 16 | Why is exercise so intimidating. Can you blog on that? Is what 17 | Danielle asked, if you have seen me recently you'd know I'm not the 18 | best person to be giving out advice about going to the gym. 19 | 20 | I will share my experiences about this though in the hope that someone 21 | else may find it useful and help them in their journey. 22 | 23 | ### #RefactorYourBody 24 | 25 | About four years ago I was convinced I was going to end up with type 26 | two diabetes. 27 | 28 | Back then I knew relativity nothing about nutrition and fitness You 29 | probably will feel like a berk in the gym, I know I did, then you 30 | realise that everyone else there is there to do the same thing and 31 | they're probably feeling like you or have felt like you feel now in 32 | the past at some point. No one is there to judge, everyone had to 33 | start somewhere. 34 | 35 | Five and two diet 36 | 37 | Gym 38 | 39 | A whole new world 🙃 40 | 41 | I'm not an expert, the fitness industry is massive and unregulated, 42 | any gymbro can open a YouTube channel and be the defacto expert on 43 | whatever it is they're peddling. 44 | 45 | It's like with any industry there's shysters and there's people who 46 | offer genuine advice. 47 | 48 | People want to be given a sheet to work from and think hey that's it, 49 | I do this then I'll look like Anthony Joshua in a couple of weeks, 50 | easy! The truth is it's hard, really hard, if it was easy everyone 51 | would be doing it! 52 | 53 | Calories 54 | 55 | Surplus = Gain weight 56 | 57 | Deficit = Lose weight 58 | 59 | Macros 60 | 61 | What are macros? 62 | 63 | Macros make up the calorie content of food: 64 | 65 | 1 gram of fat = 9 calories 66 | 67 | 1 gram of carbs (carbohydrates) = 4 calories 68 | 69 | 1 gram of protein = 4 calories 70 | 71 | Don't treat any of them as bad, there's no ‘bad' macros 72 | 73 | Plan your food 74 | 75 | Stay consistent 76 | 77 | nutrition first workout last 78 | 79 | Be aware of the calories you're consuming, this is hard I know and 80 | you'll probably think your developing some form of obsessive 81 | compulsive disorder and you'll be ‘that person' when you go out with 82 | your friends to eat — this is where the consistency comes in. 83 | 84 | https://tdeecalculator.net/ 85 | 86 | TDEE Calculator: Learn Your Total Daily Energy Expenditure Use the 87 | TDEE calculator to learn your Total Daily Energy Expenditure, a 88 | measure of how many calories you burn per day… tdeecalculator.net 89 | 90 | Alcohol, stop it! It pains me to say that as I love a beer but beers 91 | are empty calories, you can fit it with your macros if you like but 92 | it's better to limit it drastically, drink four times a week? Half it, 93 | drink once a week? Drink every other weekend, some sort of system like 94 | that. 95 | 96 | What do you want to go to the gym for? Lose a bit of weight and 'tone 97 | up'? 98 | 99 | How do you think this 'tone up' is going to work? 100 | 101 | Want to lose the love handles? Better do some core exercises, right? 102 | 103 | Let's do some isolation work on that 104 | 105 | Ab work outs, crunches, sit ups, that thing where someone holds a 20 106 | kg plate and leans over to the side… those will not target and burn 107 | belly fat, you can't specify where you want your body to burn fat, 108 | that is a myth, you burn fat all over your body. Love handles is 109 | genetically where your body is designed to store your fat reserves. 110 | 111 | Get your heart rate up! 112 | 113 | You need to work for it 114 | 115 | Program, 5x5 116 | 117 | 16/8 fasting 118 | 119 | If it was easy everyone would be doing it 120 | 121 | Get up and make it happen 122 | -------------------------------------------------------------------------------- /posts/private/yak-shaving/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | date: 2018-09-01 3 | title: Shaving the Yak! 4 | tags: ['procrastination', 'productivity'] 5 | private: true 6 | --- 7 | 8 | Don't save the yak! 9 | 10 | http://sethgodin.typepad.com/seths_blog/2005/03/dont_shave_that.html 11 | 12 | https://en.wiktionary.org/wiki/yak_shaving 13 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["config:base"], 3 | "reviewers": ["spences10"], 4 | "bumpVersion": "patch", 5 | "baseBranches": ["patch"], 6 | "automerge": true, 7 | "major": { 8 | "automerge": false 9 | }, 10 | "packageRules": [ 11 | { 12 | "packagePatterns": ["^eslint"], 13 | "groupName": "eslint" 14 | }, 15 | { 16 | "packagePatterns": ["gatsby"], 17 | "groupName": "gatsby" 18 | }, 19 | { 20 | "packagePatterns": ["@mdx-js"], 21 | "groupName": "@mdx-js" 22 | }, 23 | { 24 | "packageNames": ["react", "react-dom"], 25 | "groupName": "react" 26 | } 27 | ], 28 | "labels": ["renovate"], 29 | "prHourlyLimit": 1, 30 | "prConcurrentLimit": 5, 31 | "rangeStrategy": "bump", 32 | "semanticCommits": true, 33 | "schedule": "before 5am on Monday" 34 | } 35 | 36 | -------------------------------------------------------------------------------- /root-wrapper.js: -------------------------------------------------------------------------------- 1 | import { MDXProvider } from '@mdx-js/react' 2 | import React from 'react' 3 | import { ThemeProvider } from 'styled-components' 4 | import { Layout } from './src/components/layout' 5 | import { 6 | A, 7 | Blockquote, 8 | Br, 9 | Code, 10 | CodeWrapper, 11 | H1, 12 | H2, 13 | H3, 14 | H4, 15 | Hr, 16 | Img, 17 | InlineCode, 18 | Li, 19 | P, 20 | Small, 21 | Table, 22 | Ul, 23 | } from './src/components/page-elements' 24 | import { AnalyticsProvider } from './src/contexts/event-tracking' 25 | import { GlobalStyle, theme } from './src/theme/global-style' 26 | 27 | const components = { 28 | a: props => , 29 | blockquote: props =>
, 30 | br: props =>
, 31 | // div: props =>
, 32 | h1: props =>

, 33 | h2: props =>

, 34 | h3: props =>

, 35 | h4: props =>

, 36 | hr: props =>
, 37 | img: props => , 38 | li: props =>
  • , 39 | p: props =>

    , 40 | 'p.inlineCode': props => , 41 | pre: ({ children: { props } }) => { 42 | if (props.mdxType === 'code') { 43 | return ( 44 | 45 | 53 | 54 | ) 55 | } 56 | }, 57 | small: props => , 58 | table: props => , 59 | ul: props =>
      , 60 | wrapper: ({ children }) => <>{children}, 61 | } 62 | 63 | export const wrapPageElement = ({ element }) => ( 64 | 65 | 66 | 67 | 68 | {element} 69 | 70 | 71 | 72 | ) 73 | -------------------------------------------------------------------------------- /src/components/dump.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export const Dump = props => ( 4 |
      12 | {Object.entries(props).map(([key, val]) => ( 13 |
      14 |         
      15 |           {key} 💩
      16 |         
      17 |         {JSON.stringify(val, '', ' ')}
      18 |       
      19 | ))} 20 |
      21 | ) 22 | 23 | export default Dump 24 | -------------------------------------------------------------------------------- /src/components/header.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Helmet } from 'react-helmet' 3 | import styled, { keyframes } from 'styled-components' 4 | import moon from '../../static/moon.svg' 5 | import sun from '../../static/sun.svg' 6 | import { useLocalStorage } from '../hooks/use-local-storage' 7 | import { Link } from './shared' 8 | 9 | const StyledLink = styled(Link)` 10 | text-decoration: none; 11 | &:hover { 12 | text-decoration: underline; 13 | } 14 | &:active { 15 | color: ${({ theme }) => theme.colours.primary[500]}; 16 | } 17 | ` 18 | 19 | // For the gradient thing, check 20 | // https://github.com/fkhadra/react-toastify-doc/blob/e09ea2aabc/src/components/Actions.styles.ts 21 | // https://github.com/ChristopherBiscardi/christopherbiscardi.github.com/blob/pure-mdx/packages/www/src/components/convertkit-form/index.js#L17 22 | // https://github.com/ChristopherBiscardi/christopherbiscardi.github.com/blob/1fb406eafae449124f47179b08b2e2b2e4aa5dc6/packages/www/src/page-wrapper.js#L418 23 | 24 | // Examples: https://codesandbox.io/s/muddy-sun-gp0el?file=/src/App.js:105-504 25 | 26 | const thingAnim = keyframes` 27 | 0% { background-position: 0 0; } 28 | 50% { background-position: 400% 0; } 29 | 100% { background-position: 0 0; } 30 | ` 31 | 32 | const HeaderWrapper = styled.header` 33 | position: relative; 34 | h1 { 35 | font-family: ${({ theme }) => theme.font.monospace}; 36 | font-size: ${({ theme }) => theme.fontSize['4xl']}; 37 | font-weight: ${({ theme }) => theme.fontWeight.semibold}; 38 | margin-top: ${({ theme }) => theme.spacing[2]}; 39 | padding-bottom: ${({ theme }) => theme.spacing[1]}; 40 | padding-right: ${({ theme }) => theme.spacing[16]}; 41 | line-height: ${({ theme }) => theme.lineHeight.none}; 42 | background: linear-gradient( 43 | var( 44 | --title-gradient-from, 45 | ${({ theme }) => theme.colours.primary[200]} 46 | ), 47 | var( 48 | --title-gradient-to, 49 | ${({ theme }) => theme.colours.primary[500]} 50 | ) 51 | ); 52 | -webkit-background-clip: text; 53 | background-clip: text; 54 | -webkit-text-fill-color: transparent; 55 | } 56 | p { 57 | font-family: ${({ theme }) => theme.font.sans}; 58 | font-size: ${({ theme }) => theme.fontSize.xs}; 59 | margin-top: ${({ theme }) => theme.spacing[0]}; 60 | font-weight: ${({ theme }) => theme.fontWeight.light}; 61 | letter-spacing: ${({ theme }) => theme.letterSpacing.wide}; 62 | color: var( 63 | --colour-on-background, 64 | ${({ theme }) => theme.colours.grey[900]} 65 | ); 66 | background: linear-gradient( 67 | 90deg, 68 | var(--rainbow-one, #9349f0), 69 | var(--rainbow-two, #8f6f14), 70 | var(--rainbow-three, #da0498), 71 | var(--rainbow-four, #b05d2e), 72 | var(--rainbow-five, #864bfe), 73 | var(--rainbow-six, #cc4438), 74 | var(--rainbow-one, #a269ee) 75 | ) 76 | 0% 0% / 400%; 77 | animation: ${thingAnim} 180s ease-in-out infinite; 78 | -webkit-background-clip: text; 79 | background-clip: text; 80 | -webkit-text-fill-color: transparent; 81 | &:hover { 82 | animation: ${thingAnim} 50s ease-in-out infinite; 83 | } 84 | } 85 | button { 86 | background: none; 87 | border: none; 88 | position: absolute; 89 | top: 0.5rem; 90 | right: 0.5rem; 91 | img { 92 | width: 20px; 93 | } 94 | border-radius: ${({ theme }) => theme.borderRadius.full}; 95 | outline: none; 96 | &:active { 97 | box-shadow: ${({ theme }) => theme.boxShadow.outline}; 98 | } 99 | } 100 | ` 101 | 102 | export const Header = ({ siteTitle, siteDescription }) => { 103 | const [theme, setTheme] = useLocalStorage('theme', 'light') 104 | 105 | return ( 106 | 107 | 108 | 109 | 110 | 111 |

      {siteTitle}

      112 |

      {siteDescription}

      113 |
      114 | 123 |
      124 | ) 125 | } 126 | -------------------------------------------------------------------------------- /src/components/layout.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { down, up } from 'styled-breakpoints' 3 | import styled from 'styled-components' 4 | import { useSiteMetadata } from '../hooks/use-site-metadata' 5 | import { Header } from './header' 6 | 7 | const AppStyles = styled.main` 8 | max-width: 640px; 9 | margin: 0 auto; 10 | padding: 0 20px; 11 | ${down('sm')} { 12 | /* background-color: seagreen; */ 13 | } 14 | ${up('md')} { 15 | /* background-color: dodgerblue; */ 16 | } 17 | ${up('lg')} { 18 | /* background-color: rebeccapurple; */ 19 | } 20 | ${up('xl')} { 21 | /* background-color: hotpink; */ 22 | } 23 | ` 24 | 25 | export const Layout = ({ children }) => { 26 | const { title, description } = useSiteMetadata() 27 | return ( 28 | 29 |
      30 | {children} 31 | 32 | ) 33 | } 34 | -------------------------------------------------------------------------------- /src/components/page-elements/a.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from 'styled-components' 3 | import { inlineCode } from './inline-code' 4 | 5 | export const StyledA = styled.a` 6 | text-decoration: underline; 7 | color: var( 8 | --colour-on-background, 9 | ${({ theme }) => theme.colours.grey[900]} 10 | ); 11 | text-decoration-color: var( 12 | --colour-on-background, 13 | ${({ theme }) => theme.colours.grey[900]} 14 | ); 15 | &:hover { 16 | opacity: 0.5; 17 | } 18 | code { 19 | ${inlineCode} 20 | } 21 | ` 22 | 23 | export const A = props => { 24 | return ( 25 | 26 | {props.children} 27 | 28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /src/components/page-elements/blockquote.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from 'styled-components' 3 | 4 | const StyledText = styled.blockquote` 5 | margin: 20px; 6 | p { 7 | margin-top: 0; 8 | border-left: 5px solid ${({ theme }) => theme.colours.grey[700]}; 9 | padding-left: 15px; 10 | font-style: italic; 11 | font-size: ${({ theme }) => theme.fontSize['2xl']}; 12 | color: var(--colour-on-background); 13 | word-break: break-word; 14 | } 15 | ` 16 | 17 | export const Blockquote = ({ children }) => { 18 | return {children} 19 | } 20 | -------------------------------------------------------------------------------- /src/components/page-elements/br.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from 'styled-components' 3 | 4 | const StyledText = styled.br` 5 | margin-bottom: ${({ theme }) => theme.spacing[6]}; 6 | ` 7 | 8 | export const Br = ({ children }) => { 9 | return {children} 10 | } 11 | -------------------------------------------------------------------------------- /src/components/page-elements/code.js: -------------------------------------------------------------------------------- 1 | import Highlight, { defaultProps } from 'prism-react-renderer' 2 | import theme from 'prism-react-renderer/themes/nightOwl' 3 | import React from 'react' 4 | import { 5 | LiveEditor, 6 | LiveError, 7 | LivePreview, 8 | LiveProvider, 9 | } from 'react-live' 10 | import styled from 'styled-components' 11 | import 'victormono' 12 | import { copyToClipboard } from '../../utils/copy-to-clipboard' 13 | import { CustomScroll, NegMargin } from '../shared' 14 | 15 | const RE = /{([\d,-]+)}/ 16 | 17 | export const CodeWrapper = styled.div` 18 | position: relative; 19 | ${NegMargin}; 20 | margin-top: ${({ theme }) => theme.spacing['10']}; 21 | margin-bottom: ${({ theme }) => theme.spacing['10']}; 22 | * { 23 | font-family: 'Victor Mono', 'Courier New', Courier, monospace; 24 | } 25 | overflow: hidden; 26 | border-radius: 5px; 27 | ` 28 | 29 | const Pre = styled.pre` 30 | text-align: left; 31 | padding: 0.5em; 32 | ${({ ligatures }) => ligatures && `font-variant-ligatures: none;`}; 33 | overflow: hidden; 34 | overflow-x: auto; 35 | float: left; 36 | min-width: 100%; 37 | ` 38 | 39 | const LineNo = styled.span` 40 | display: inline-block; 41 | width: 1.8em; 42 | user-select: none; 43 | opacity: 0.3; 44 | ` 45 | 46 | const CopyCode = styled.button` 47 | position: absolute; 48 | right: 0.25rem; 49 | border: 0; 50 | border-radius: 3px; 51 | margin-right: ${({ theme }) => theme.spacing[1]}; 52 | padding: ${({ theme }) => theme.spacing[1]}; 53 | color: ${({ theme }) => theme.colours.grey[500]}; 54 | &:hover { 55 | background-color: ${({ theme }) => theme.colours.grey[100]}; 56 | color: ${({ theme }) => theme.colours.grey[900]}; 57 | } 58 | background-color: ${({ theme }) => theme.colours.primary[500]}; 59 | ` 60 | 61 | function calculateLinesToHighlight(meta) { 62 | if (RE.test(meta)) { 63 | const lineNumbers = RE.exec(meta)[1] 64 | .split(',') 65 | .map(v => v.split('-').map(y => parseInt(y, 10))) 66 | return index => { 67 | const lineNumber = index + 1 68 | const inRange = lineNumbers.some(([start, end]) => 69 | end 70 | ? lineNumber >= start && lineNumber <= end 71 | : lineNumber === start 72 | ) 73 | return inRange 74 | } 75 | } else { 76 | return () => false 77 | } 78 | } 79 | 80 | const Wrapper = styled.div` 81 | overflow: auto; 82 | ${CustomScroll}; 83 | &::-webkit-scrollbar { 84 | width: 11px; 85 | } 86 | ` 87 | 88 | export const Code = ({ codeString, language, ...props }) => { 89 | const shouldHighlightLine = calculateLinesToHighlight( 90 | props.metastring 91 | ) 92 | if (props['react-live']) { 93 | return ( 94 | 95 | 96 | 97 | 98 | 99 | ) 100 | } 101 | const handleClick = () => { 102 | copyToClipboard(codeString) 103 | } 104 | return ( 105 | 106 | 112 | {({ 113 | className, 114 | style, 115 | tokens, 116 | getLineProps, 117 | getTokenProps, 118 | }) => ( 119 |
      120 |             Copy
      121 |             {tokens.map((line, i) => (
      122 |               
      131 | {i + 1} 132 | {line.map((token, key) => ( 133 | 134 | ))} 135 |
      136 | ))} 137 |
      138 | )} 139 |
      140 |
      141 | ) 142 | } 143 | -------------------------------------------------------------------------------- /src/components/page-elements/div.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from 'styled-components' 3 | 4 | export const StyledDiv = styled.div`` 5 | 6 | export const Div = (props, { children }) => { 7 | return {children} 8 | } 9 | -------------------------------------------------------------------------------- /src/components/page-elements/h1.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from 'styled-components' 3 | import { AutoLink } from './linked-headers' 4 | 5 | const StyledText = styled.h1` 6 | font-size: ${({ theme }) => theme.fontSize['4xl']}; 7 | font-family: ${({ theme }) => theme.font.serif}; 8 | ${AutoLink}; 9 | margin-top: ${({ theme }) => theme.spacing[8]}; 10 | line-height: ${({ theme }) => theme.lineHeight.none}; 11 | ` 12 | 13 | export const H1 = props => { 14 | return {props.children} 15 | } 16 | -------------------------------------------------------------------------------- /src/components/page-elements/h2.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from 'styled-components' 3 | import { inlineCode } from './inline-code' 4 | import { AutoLink } from './linked-headers' 5 | 6 | const StyledText = styled.h2` 7 | font-size: ${({ theme }) => theme.fontSize['3xl']}; 8 | font-family: ${({ theme }) => theme.font.serif}; 9 | ${AutoLink}; 10 | margin-top: ${({ theme }) => theme.spacing[12]}; 11 | margin-bottom: ${({ theme }) => theme.spacing[6]}; 12 | line-height: ${({ theme }) => theme.lineHeight.none}; 13 | code { 14 | ${inlineCode} 15 | } 16 | ` 17 | 18 | export const H2 = props => { 19 | return {props.children} 20 | } 21 | -------------------------------------------------------------------------------- /src/components/page-elements/h3.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from 'styled-components' 3 | import { AutoLink } from './linked-headers' 4 | 5 | const StyledText = styled.h3` 6 | font-size: ${({ theme }) => theme.fontSize['2xl']}; 7 | font-family: ${({ theme }) => theme.font.serif}; 8 | ${AutoLink}; 9 | margin-top: ${({ theme }) => theme.spacing[8]}; 10 | line-height: ${({ theme }) => theme.lineHeight.none}; 11 | ` 12 | 13 | export const H3 = props => { 14 | return {props.children} 15 | } 16 | -------------------------------------------------------------------------------- /src/components/page-elements/h4.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from 'styled-components' 3 | import { AutoLink } from './linked-headers' 4 | 5 | const StyledText = styled.h4` 6 | font-size: ${({ theme }) => theme.fontSize['1xl']}; 7 | font-family: ${({ theme }) => theme.font.serif}; 8 | ${AutoLink}; 9 | margin-top: ${({ theme }) => theme.spacing[6]}; 10 | line-height: ${({ theme }) => theme.lineHeight.none}; 11 | ` 12 | 13 | export const H4 = props => { 14 | return {props.children} 15 | } 16 | -------------------------------------------------------------------------------- /src/components/page-elements/hr.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from 'styled-components' 3 | 4 | const StyledHr = styled.hr` 5 | margin: 60px 0; 6 | opacity: 0.5; 7 | color: ${({ theme }) => theme.colours.grey[300]}; 8 | ` 9 | 10 | export const Hr = props => { 11 | return {props.children} 12 | } 13 | -------------------------------------------------------------------------------- /src/components/page-elements/img.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from 'styled-components' 3 | 4 | const StyledImg = styled.img` 5 | &:hover { 6 | opacity: 0.5; 7 | } 8 | box-shadow: var(--box-shadow-xl); 9 | ` 10 | 11 | export const Img = props => { 12 | const { children, ...rest } = props 13 | 14 | return ( 15 | <> 16 | {rest.className === `gatsby-resp-image-image` ? ( 17 | {children} 18 | ) : ( 19 | 20 | {children} 21 | 22 | )} 23 | 24 | ) 25 | } 26 | -------------------------------------------------------------------------------- /src/components/page-elements/index.js: -------------------------------------------------------------------------------- 1 | export * from './a' 2 | export * from './blockquote' 3 | export * from './br' 4 | export * from './code' 5 | export * from './div' 6 | export * from './h1' 7 | export * from './h2' 8 | export * from './h3' 9 | export * from './h4' 10 | export * from './hr' 11 | export * from './img' 12 | export * from './inline-code' 13 | export * from './li' 14 | export * from './p' 15 | export * from './small' 16 | export * from './table' 17 | export * from './ul' 18 | -------------------------------------------------------------------------------- /src/components/page-elements/inline-code.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled, { css } from 'styled-components' 3 | import 'victormono' 4 | 5 | export const inlineCode = css` 6 | padding: 0 3px; 7 | background-color: var( 8 | --colour-on-secondary, 9 | ${({ theme }) => theme.colours.grey[300]} 10 | ); 11 | font-family: 'Victor Mono', monospace; 12 | border-radius: ${({ theme }) => theme.borderRadius.sm}; 13 | ` 14 | 15 | const StyledText = styled.code` 16 | ${inlineCode} 17 | ` 18 | 19 | export const InlineCode = ({ children }) => { 20 | return {children} 21 | } 22 | -------------------------------------------------------------------------------- /src/components/page-elements/li.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from 'styled-components' 3 | 4 | export const StyledLi = styled.li` 5 | list-style-type: circle; 6 | margin-bottom: ${({ theme }) => theme.spacing[2]}; 7 | word-break: break-word; 8 | line-height: ${({ theme }) => theme.lineHeight.tight}; 9 | p { 10 | margin-top: 10px; 11 | } 12 | ` 13 | 14 | export const Li = props => { 15 | return {props.children} 16 | } 17 | -------------------------------------------------------------------------------- /src/components/page-elements/linked-headers.js: -------------------------------------------------------------------------------- 1 | export const AutoLink = ` 2 | a { 3 | float: left; 4 | margin-left: -24px; 5 | } 6 | svg { 7 | visibility: hidden; 8 | } 9 | &:hover { 10 | svg { 11 | visibility: visible; 12 | height: 25px; 13 | width: 20px; 14 | fill: var( 15 | --colour-on-background, 16 | ${({ theme }) => theme.colours.grey[900]}); 17 | } 18 | } 19 | ` 20 | -------------------------------------------------------------------------------- /src/components/page-elements/p.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from 'styled-components' 3 | import { inlineCode } from './inline-code' 4 | 5 | const StyledText = styled.p` 6 | font-size: ${({ theme }) => theme.fontSize.base}; 7 | margin-bottom: ${({ theme }) => theme.spacing[6]}; 8 | strong { 9 | font-weight: 500; 10 | } 11 | em { 12 | font-style: italic; 13 | code { 14 | ${inlineCode} 15 | } 16 | } 17 | img { 18 | width: 100%; 19 | } 20 | word-break: break-word; 21 | ` 22 | 23 | export const P = props => { 24 | const { children, ...rest } = props 25 | return {children} 26 | } 27 | -------------------------------------------------------------------------------- /src/components/page-elements/small.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from 'styled-components' 3 | 4 | export const StyledSmall = styled.span` 5 | font-size: ${({ theme }) => theme.fontSize.xs}; 6 | ` 7 | 8 | export const Small = props => { 9 | return {props.children} 10 | } 11 | -------------------------------------------------------------------------------- /src/components/page-elements/table.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from 'styled-components' 3 | 4 | export const StyledTable = styled.table` 5 | margin-top: ${({ theme }) => theme.spacing[10]}; 6 | margin-bottom: ${({ theme }) => theme.spacing[10]}; 7 | font-size: ${({ theme }) => theme.fontSize.sm}; 8 | width: 100%; 9 | thead { 10 | font-size: ${({ theme }) => theme.fontSize.base}; 11 | font-weight: ${({ theme }) => theme.fontWeight.medium}; 12 | background-color: var( 13 | --colour-secondary, 14 | ${({ theme }) => theme.colours.grey[300]} 15 | ); 16 | border: 1px solid ${({ theme }) => theme.colours.grey[500]}; 17 | } 18 | th, 19 | td { 20 | border: 1px solid 21 | var( 22 | --colour-on-secondary, 23 | ${({ theme }) => theme.colours.grey[400]} 24 | ); 25 | } 26 | th, 27 | td { 28 | padding-left: ${({ theme }) => theme.spacing[2]}; 29 | padding-right: ${({ theme }) => theme.spacing[3]}; 30 | padding-top: ${({ theme }) => theme.spacing[2]}; 31 | padding-bottom: ${({ theme }) => theme.spacing[1]}; 32 | text-align: left; 33 | } 34 | th, 35 | td { 36 | &:hover { 37 | background-color: var( 38 | --colour-on-secondary, 39 | ${({ theme }) => theme.colours.grey[400]} 40 | ); 41 | } 42 | } 43 | ` 44 | 45 | export const Table = props => { 46 | return {props.children} 47 | } 48 | -------------------------------------------------------------------------------- /src/components/page-elements/ul.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from 'styled-components' 3 | 4 | const Wrapper = styled.div` 5 | margin-bottom: ${({ theme }) => theme.spacing[6]}; 6 | ` 7 | 8 | export const StyledUl = styled.ul` 9 | margin: 0 ${({ theme }) => theme.spacing[4]}; 10 | ` 11 | 12 | export const Ul = props => { 13 | return ( 14 | 15 | {props.children} 16 | 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /src/components/post-reactions.js: -------------------------------------------------------------------------------- 1 | // What do you think? 2 | /** 3 | * Nice! thumbs-up.png 4 | * Love it! love.png 5 | * No good yo! angry.png 6 | * Can't even! surprised.png 7 | * LOL! funny.png 8 | */ 9 | // animation: anim-hop 1s ease-in-out infinite alternate; 10 | -------------------------------------------------------------------------------- /src/components/share.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { TwitterShareButton } from 'react-share' 3 | import styled from 'styled-components' 4 | 5 | const ShareWrapper = styled.section` 6 | h6 { 7 | background: linear-gradient( 8 | 0.25turn, 9 | var( 10 | --title-gradient-from, 11 | ${({ theme }) => theme.colours.primary[200]} 12 | ), 13 | var( 14 | --title-gradient-to, 15 | ${({ theme }) => theme.colours.primary[500]} 16 | ) 17 | ); 18 | -webkit-background-clip: text; 19 | background-clip: text; 20 | -webkit-text-fill-color: transparent; 21 | } 22 | span { 23 | font-weight: 500; 24 | } 25 | ` 26 | 27 | export const Share = ({ url, title, twitterHandle }) => { 28 | return ( 29 | 30 | 35 |
      36 | Useful? Click here to share this post on 37 | Twitter. 38 |
      39 |
      40 |
      41 | ) 42 | } 43 | -------------------------------------------------------------------------------- /src/components/shared.js: -------------------------------------------------------------------------------- 1 | import { Link as GatsbyLink } from 'gatsby' 2 | import React from 'react' 3 | import { down } from 'styled-breakpoints' 4 | import styled, { css } from 'styled-components' 5 | 6 | export const Link = styled(props => )`` 7 | 8 | export const PostInfo = styled.div` 9 | margin-top: ${({ theme }) => theme.spacing[0]}; 10 | color: ${({ theme }) => theme.colours.grey[700]}; 11 | font-size: ${({ theme }) => theme.fontSize.xs}; 12 | font-weight: ${({ theme }) => theme.fontWeight.normal}; 13 | text-transform: uppercase; 14 | display: inline-grid; 15 | grid-template-columns: auto auto auto; 16 | grid-template-rows: auto; 17 | grid-template-areas: 'date ttr edit'; 18 | ${down('sm')} { 19 | grid-template-columns: repeat(1, 1fr); 20 | grid-template-areas: 21 | 'date' 22 | 'ttr' 23 | 'edit'; 24 | } 25 | ` 26 | 27 | export const PostTimeToRead = styled.div` 28 | grid-area: ttr; 29 | margin-right: ${({ theme }) => theme.spacing[1]}; 30 | ` 31 | 32 | export const PostEditOnGitHub = styled.div` 33 | grid-area: edit; 34 | &:before { 35 | content: '· '; 36 | } 37 | ${down('sm')} { 38 | &:before { 39 | content: ''; 40 | } 41 | } 42 | a { 43 | color: ${({ theme }) => theme.colours.grey[700]}; 44 | text-decoration: underline; 45 | text-decoration-color: ${({ theme }) => theme.colours.grey[700]}; 46 | &:hover { 47 | opacity: 0.5; 48 | } 49 | cursor: pointer; 50 | } 51 | ` 52 | 53 | export const CopyWrapper = styled.div` 54 | padding: ${({ theme }) => theme.spacing[4]}; 55 | ` 56 | 57 | export const StyledTitle = styled.h1` 58 | font-size: ${({ theme }) => theme.fontSize['3xl']}; 59 | font-family: ${({ theme }) => theme.font.serif}; 60 | line-height: ${({ theme }) => theme.lineHeight.none}; 61 | ` 62 | 63 | export const StyledExcerpt = styled.p` 64 | margin-top: ${({ theme }) => theme.spacing[3]}; 65 | ` 66 | 67 | export const StyledLink = styled(Link)` 68 | text-decoration: none; 69 | ` 70 | 71 | export const IndexWrapper = styled.main`` 72 | 73 | export const NegMargin = css` 74 | margin-left: -${({ theme }) => theme.spacing[12]}; 75 | margin-right: -${({ theme }) => theme.spacing[12]}; 76 | ${down('sm')} { 77 | margin-left: -${({ theme }) => theme.spacing[0]}; 78 | margin-right: -${({ theme }) => theme.spacing[0]}; 79 | } 80 | ` 81 | 82 | // https://css-tricks.com/the-current-state-of-styling-scrollbars/ 83 | export const CustomScroll = css` 84 | scrollbar-width: thin; 85 | scrollbar-color: var(--thumb-bg) var(--scrollbar-bg); 86 | &::-webkit-scrollbar { 87 | width: 15px; 88 | } 89 | &::-webkit-scrollbar-track { 90 | background: var(--scrollbar-bg); 91 | } 92 | &::-webkit-scrollbar-thumb { 93 | background-color: var(--thumb-bg); 94 | border-radius: 14px; 95 | border: 3px solid var(--scrollbar-bg); 96 | } 97 | ` 98 | -------------------------------------------------------------------------------- /src/contexts/event-tracking.js: -------------------------------------------------------------------------------- 1 | import React, { createContext, useContext, useEffect } from 'react' 2 | const activeEnv = 3 | process.env.ACTIVE_ENV || process.env.NODE_ENV || 'development' 4 | 5 | const AnalyticsContext = createContext({}) 6 | 7 | export const AnalyticsProvider = ({ children }) => { 8 | useEffect(() => { 9 | if (activeEnv === 'development') { 10 | window.fathom.trackGoal = (x, y) => { 11 | console.log(`I'm a fake event`, x, y) 12 | } 13 | } 14 | }, []) 15 | 16 | const logClicks = goalId => { 17 | window.fathom.trackGoal(goalId, 0) 18 | } 19 | 20 | return ( 21 | 22 | {children} 23 | 24 | ) 25 | } 26 | 27 | export const useAnalytics = () => { 28 | return useContext(AnalyticsContext) 29 | } 30 | -------------------------------------------------------------------------------- /src/hooks/use-local-storage.js: -------------------------------------------------------------------------------- 1 | // https://www.youtube.com/watch?v=BAf0uhKVHBk 2 | import { useEffect, useState } from 'react' 3 | 4 | export const useLocalStorage = (key, defaultValue) => { 5 | const [value, setValue] = useState(() => { 6 | if (typeof window === 'undefined') { 7 | // console.log(`We SSR yo!`) 8 | return 9 | } 10 | 11 | const storedValue = localStorage.getItem(key) 12 | return storedValue === null 13 | ? defaultValue 14 | : JSON.parse(storedValue) 15 | }) 16 | 17 | useEffect(() => { 18 | const listener = e => { 19 | if (e.storedArea === localStorage && e.key === key) { 20 | setValue(JSON.parse(e.newValue)) 21 | } 22 | } 23 | window.addEventListener('storage', listener) 24 | 25 | return () => { 26 | window.removeEventListener('storage', listener) 27 | } 28 | }, [key]) 29 | 30 | const setValueInLocalStorage = newValue => { 31 | setValue(currentValue => { 32 | const result = 33 | typeof newValue === 'function' 34 | ? newValue(currentValue) 35 | : newValue 36 | localStorage.setItem(key, JSON.stringify(result)) 37 | return result 38 | }) 39 | } 40 | 41 | return [value, setValueInLocalStorage] 42 | } 43 | -------------------------------------------------------------------------------- /src/hooks/use-site-metadata.js: -------------------------------------------------------------------------------- 1 | import { graphql, useStaticQuery } from 'gatsby' 2 | 3 | export const useSiteMetadata = () => { 4 | const { site } = useStaticQuery( 5 | graphql` 6 | query SITE_METADATA_QUERY { 7 | site { 8 | siteMetadata { 9 | description 10 | title 11 | image 12 | siteUrl 13 | siteLanguage 14 | siteLocale 15 | twitterUsername 16 | authorName 17 | } 18 | } 19 | } 20 | ` 21 | ) 22 | return site.siteMetadata 23 | } 24 | -------------------------------------------------------------------------------- /src/html.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types' 2 | import React from 'react' 3 | 4 | export default function HTML(props) { 5 | return ( 6 | 7 | 13 | 14 | 15 | 16 | 20 | {props.headComponents} 21 | 22 | 23 | {props.preBodyComponents} 24 |
      29 | {props.postBodyComponents} 30 | 31 | 32 | ) 33 | } 34 | 35 | HTML.propTypes = { 36 | htmlAttributes: PropTypes.object, 37 | headComponents: PropTypes.array, 38 | bodyAttributes: PropTypes.object, 39 | preBodyComponents: PropTypes.array, 40 | body: PropTypes.string, 41 | postBodyComponents: PropTypes.array, 42 | } 43 | -------------------------------------------------------------------------------- /src/pages/404.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { isIE } from 'react-device-detect' 3 | import styled from 'styled-components' 4 | import { 5 | IndexWrapper, 6 | StyledExcerpt, 7 | StyledLink, 8 | StyledTitle, 9 | } from '../components/shared' 10 | 11 | const PageWrapper = styled.div` 12 | height: 100vh; 13 | position: relative; 14 | ` 15 | 16 | const Styled404 = styled.div` 17 | position: absolute; 18 | top: 10%; 19 | width: 100%; 20 | font-size: ${({ theme }) => theme.fontSizeH2}; 21 | ` 22 | 23 | export default () => { 24 | if (isIE) 25 | return ( 26 | 27 | IE is not supported. 28 | 29 | Please use a modern browser, download Firefox, Chrome or 30 | Edge 31 | 32 | 33 | ) 34 | return ( 35 | <> 36 | 37 | 38 | That's a nope! 39 | 40 | You've come to a page that doesn't exist, pls go{' '} 41 | home. 42 | 43 | 44 | 45 | 46 | ) 47 | } 48 | -------------------------------------------------------------------------------- /src/pages/index.js: -------------------------------------------------------------------------------- 1 | import { graphql } from 'gatsby' 2 | import Img from 'gatsby-image' 3 | import React from 'react' 4 | import { isIE } from 'react-device-detect' 5 | import SEO from 'react-seo-component' 6 | import styled from 'styled-components' 7 | import { 8 | CopyWrapper, 9 | IndexWrapper, 10 | PostInfo, 11 | PostTimeToRead, 12 | StyledExcerpt, 13 | StyledLink, 14 | StyledTitle, 15 | } from '../components/shared' 16 | import { useSiteMetadata } from '../hooks/use-site-metadata' 17 | 18 | const PostWrapper = styled.div` 19 | border-radius: ${({ theme }) => theme.borderRadius.lg}; 20 | box-shadow: var( 21 | --box-shadow-lg, 22 | 0 10px 15px -3px rgba(0, 0, 0, 0.1), 23 | 0 4px 6px -2px rgba(0, 0, 0, 0.05) 24 | ); 25 | color: var( 26 | --colour-on-background, 27 | ${({ theme }) => theme.colours.grey[900]} 28 | ); 29 | overflow: hidden; 30 | &:before { 31 | height: 5px; 32 | display: block; 33 | content: ''; 34 | background: linear-gradient( 35 | 0.25turn, 36 | var( 37 | --title-gradient-from, 38 | ${({ theme }) => theme.colours.primary[200]} 39 | ), 40 | var( 41 | --title-gradient-to, 42 | ${({ theme }) => theme.colours.primary[500]} 43 | ) 44 | ); 45 | } 46 | ` 47 | 48 | const LinkWrapper = styled.div` 49 | margin: ${({ theme }) => theme.spacing[8]} 0; 50 | /* padding: 0 ${({ theme }) => theme.spacing[8]}; */ 51 | ` 52 | 53 | const Image = styled(Img)` 54 | height: ${({ theme }) => theme.spacing[56]}; 55 | object-fit: cover; 56 | ` 57 | 58 | export default ({ data }) => { 59 | const { 60 | description, 61 | title, 62 | image, 63 | siteUrl, 64 | siteLanguage, 65 | siteLocale, 66 | twitterUsername, 67 | } = useSiteMetadata() 68 | if (isIE) 69 | return ( 70 | 71 | IE is not supported. 72 | 73 | Please use a modern browser, download Firefox, Chrome or 74 | Edge 75 | 76 | 77 | ) 78 | return ( 79 | <> 80 | 90 | 91 | {/* */} 92 | {data.allMdx.nodes.map( 93 | ({ 94 | id, 95 | excerpt, 96 | frontmatter, 97 | fields: { slug, editLink }, 98 | timeToRead, 99 | }) => ( 100 | 101 | 102 | 103 | {!!frontmatter.cover ? ( 104 | 108 | ) : null} 109 | 110 | {frontmatter.title} 111 | 112 | 113 | {timeToRead * 2} minutes to read 114 | 115 | 116 | {excerpt} 117 | 118 | 119 | 120 | 121 | ) 122 | )} 123 | 124 | 125 | ) 126 | } 127 | 128 | export const query = graphql` 129 | query SITE_INDEX_QUERY { 130 | allMdx( 131 | sort: { fields: [frontmatter___date], order: DESC } 132 | filter: { frontmatter: { private: { eq: false } } } 133 | ) { 134 | nodes { 135 | id 136 | excerpt(pruneLength: 100) 137 | frontmatter { 138 | title 139 | date(formatString: "YYYY MMMM Do") 140 | } 141 | tableOfContents 142 | timeToRead 143 | fields { 144 | slug 145 | editLink 146 | } 147 | } 148 | } 149 | } 150 | ` 151 | -------------------------------------------------------------------------------- /src/utils/copy-to-clipboard.js: -------------------------------------------------------------------------------- 1 | // https://github.com/gatsbyjs/gatsby/blob/561d33e2e491d3971cb2a404eec9705a5a493602/www/src/utils/copy-to-clipboard.js 2 | 3 | export const copyToClipboard = str => { 4 | const clipboard = window.navigator.clipboard 5 | /* 6 | * fallback to older browsers (including Safari) 7 | * if clipboard API not supported 8 | */ 9 | if (!clipboard || typeof clipboard.writeText !== `function`) { 10 | const textarea = document.createElement(`textarea`) 11 | textarea.value = str 12 | textarea.setAttribute(`readonly`, true) 13 | textarea.setAttribute(`contenteditable`, true) 14 | textarea.style.position = `absolute` 15 | textarea.style.left = `-9999px` 16 | document.body.appendChild(textarea) 17 | textarea.select() 18 | const range = document.createRange() 19 | const sel = window.getSelection() 20 | sel.removeAllRanges() 21 | sel.addRange(range) 22 | textarea.setSelectionRange(0, textarea.value.length) 23 | document.execCommand(`copy`) 24 | document.body.removeChild(textarea) 25 | 26 | return Promise.resolve(true) 27 | } 28 | 29 | return clipboard.writeText(str) 30 | } 31 | -------------------------------------------------------------------------------- /static/angry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/static/angry.png -------------------------------------------------------------------------------- /static/default-site-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/static/default-site-image.jpg -------------------------------------------------------------------------------- /static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/static/favicon.png -------------------------------------------------------------------------------- /static/funny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/static/funny.png -------------------------------------------------------------------------------- /static/love.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/static/love.png -------------------------------------------------------------------------------- /static/moon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /static/sun.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /static/surprised.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/static/surprised.png -------------------------------------------------------------------------------- /static/thumbs-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spences10/thelocalhost/6805f21c3e3d466eeace0db42d04b75b7b67b750/static/thumbs-up.png --------------------------------------------------------------------------------