Devlog

A developer keeps a log.

A developer keeps a log.

Insgall NGINX

NGINX stable/mainline?

Gatsby Link / Google Tag Manager

Google Tag Manager broke Gatsby Link's client routing?!

CF Invalidation

"An invalidation path that includes the * character incurs the same charge as one that does not. You pay for one invalidation path, even if the path matches hundreds or thousands of objects."

AWS CLI

AWS CLI is already installed on GitHub-hosted runners.

Invalidate root path?

/

TypeScript fundamentals

Multiple function signatures, parameter properties, user-defined type guards, bottom types, conditional types.

Docker

Docker

react-query

useQuery, useMutation.

CloudFront

React – S3 – CloudFront.

Next.js — static optimization

Next.js has an automatic static optimization feature, which is awesome.

fromNow on static pages

I'd been rendering dates using `fromNow` formatter on a static page and dates were not changing at all. Static sites have their own pitfalls.

Motion

Used Framer Motion’s `AniamtePresence` to implement unmount animations.

Gatsby Code of Conduct

Updated the PR to use the official translation of the Contributor Covenant.

gatsby-ko

Translated Gatsby code of conduct.

Topic Log

Created a new category called topic log, which is a chronological record of a topic.

Convert JS to TS

Converted post.js template to post.tsx.

josephk.io with TypeScript

Configured the blog to use TypeScript. Used Babel and ESLint.

Configured Sentry

Configured Sentry. To use environment variables in browsers, `GATSBY_` prefix is required.

Enabled the releases feature, GitHub integration, Slack integration.

Made a local gatsby-plugin-sentry to use ZEIT Now’s commit SHA environment variable on client-side.

Blog header & footer, Sentry

Redesigned the header, the footer, and the homepage.

Configuring Sentry. Doesn't look like it's working. Initialized Sentry and wrapped the root element with ErrorBoundary. Used onClientEntry and wrapRootElement from Gatsby browser API.

Disable Forestry preview

Disabled Forestry preview feature. It exposes environment variables in the settings file.

Now’s build time has been greatly reduced.

Forestry

Configured Forestry to manage the content of the Now page. It’s a huge advantage to be able to update or post content without a terminal.

I’ve been using text format for the date field because I couldn’t configure the timezone offset. I found it today in the most obvious place.

Forestry admin page can be accessed via /admin route.

Illusrations

ESLint is a nuisance.

Added Ouch.pick's illustrations to the blog.

Google Sign-In

Implemented Google Sign-In in SPA/REST style. Google Sign-In web SDK is documented very well compared to Facebook. No need to use Passport, unlike Facebook.

Used @types/gapi.auth2 for Google SDK.

FaceBook Login

Used Passport to implement the Facebook Login feature. There are many resources for traditional websites, but not for SPAs.

Facebook's document is so bad that I had to use passport-facebook-token even though I think Passport provides little benefit.

Facebook Login

Figuring out how to verify the Facebook access token in server.

https://graph.facebook.com/v4.0/debug_token?i_ut_token={access-token}&access_token={app_id}|{app_secret}

Maybe I should just use Passport.

Next.js — render logged-in state on server

Rendering a logged-in state on the server is one of the challenges in Next.js projects. Seems like _app.js is the best place to check and verify the JWT.

Passport

Implemented authentication flow via Passport. I haven't tried Passport before and I just wanted to try it. Passport with JWT and REST API, however, doesn't seem like worth it. Maybe I missed some points, but it seems that Passport doesn't add any value.

MongoDB, Mongoose.

Multiple layouts for Next.js

Found a way to use multiple layouts other than the default one in Next.js. Add layout components as static field of page components. The custom <App> component then can determine the layout component to render.

https://spectrum.chat/next-js/general/is-there-a-way-to-persist-a-layout-for-a-given-set-of-routes~af6ca794-5420-4780-abd8-96f085a19e09?authed=true

Next.js, Express

Set up Next.js and Express projects. Redux, MongoDB.

Adding TypeScript to Next.js is very intuitive. Make an empty tsconfig.json file, then Next CLI will notice and instruct the next step.

Used Helmet on Express.

FIrebase

Watching Firebase tutorial out of curiosity.

Setup, querying and updating.

Forestry CMS

Finished API Design in Node.js course.

Setup Forestry CMS, which I’ve been thinking to give it a try for a while, for contents of devlog. Unlike with other CMS, data are not locked in a cloud. Basically, it gives you a nice writing interface and commits the content to the repository. The setup process was so simple that there was almost nothing to do on my end.

Watched GraphQL introduction course. I've been using GraphQL only in client code. The course was about implementing GraphQL API on server.

API in Node.js

Learned about Django’s basic concepts and how to use it.

Used PipEnv, which has similar concepts as npm/yarn. Now that I’m familiar with Node.js, it feels more natural than other options to me.

Project, app, template, view, class-based view, URL, extending template.

API Design in Node.js course.

Learn MongoDB

Finished “Introduction to MongoDB” course.

Learned how to use Python Virtualenv. What is virtualenvwrapper?

Learn MongoDB

Started “Introduction to MongoDB” course on FEM.

React with TypeScript

My last experience with TypeScript and ESLint was awful. I had chosen ESLint back then only because I heard that TSLint will be deprecated. In retrospect, it was a naive and premature decision. ESLint was simply not ready.

React SSR – Parcel, Reach Router, Express

Conceptually, React SSR is simple. Learned the difference between render and hydrate.

Use hooks

Learned React's relatively new concepts. useEffect, StrictMode, getDerivedStateFromProps, ErrorBoundary, getDerivedStateFromError, Context, useContext, useRef, useReducer, useMemo, useCallback, useLayoutEffect, Portal.

Event delegation still works on Portal, which is located outside the app root.

Reach router, memoize-one.

Learn React again

Learned some of React's basic concepts again to refresh myself.

Move an item around

Finally, I started implementing the dragging feature. As I expected, it didn't go well. Trying to make items avoid as a dragged item moves around.

Long-press a row item inside a ScrollView to drag around

Spent all day figuring out how to drag an item inside a ScrollView only if it was long-pressed. After a lot of experiments, I found a working implementation that uses simultaneousHandlers, NativeViewGestureHandler and LongPressGestureHandler.

Animated `TextInput`

Animated.TextInput can handle animated value prop. Reanimated.TextInput’s text prop can be a Reanimated.Value.

Clear pinch

PinchGestureHandler provides scale value as a callback parameter.

Projectile with drag. Force accelleration velocity position.

Phenakistiscipe

Made a phenakistiscipe using Canvas API and wrote a post about it.

Phenakistiscope

I saw something called phenakistiscope, which is an old animation device. It is so cool that I made a web version of animated disc with ordinary HTML elements. Should've used Canvas.

Python

(Python) Class, exception.

Object falling under gravity and drag.

josephk.io

Bought and applied the new domain name, josephk.io. Setup and deployed an empty project to Zeit Now for redirections. josephk.io, dhk.party and www.dhk.party redirects to www.josephk.io now.

React.memo memoizes the result and avoids unnecessary renders.

Modified full-screen menu component to look like a sidebar.

Seems like there is no option for invoking a callback after programmatic navigation in Gatsby project. I'm thinking of something like Next's Router.push, which returns a promise.

Reanimated

Learned a few cool things related to animation: Perlin Noise, vector, displacement, velocity, acceleration.

RN – Instagram Stories

Watched William Candillon's video to copy swipe animation of Instagram Stories. Tried my own approach after that to make it straightforward and robust. It worked out well and I like the result very much.

Reanimated

Reanimated — Google Chrome Refresh, 3D card folding

IntersectionObserver

Used IntersectionObserver to implement a collapsible header. Noticed that sometimes events are not fired. Used useEffect hook for the first time in doing so.

Dark mode

Saw RN animation tutorials: Flipboard's folding animation, Airbnb-style intro animation.

Added dark mode to the blog. Dark mode is more educational feature than I first thought, especially for web developers. Static site makes the problem more challenging.

MaskedViewIOS, react-native-svg

Used RN MakedViewIOS for the first time. Good to know it exists.

Used react-native-svg to implement an animation that a point moves along the line of a chart as I swipe. It was very sluggish since (x, y) points were calculated on JS thread. Should try again using Reanimated so that the calculation happens on UI thread.

Webhook

gatsby-background-image renders the same image on multiple instances of a component. I was using Emotion’s css prop to set the height of the element so that the background is visible. Seems like the component uses className to find a specific target instance to set an image URL. Used plain style obejct instead of Emotion.

Configured Contentful to call the ZEIT Now webhook on content publish.

Journal on Contentful

Set up Journal category using Contentful.

Headless CMS

Looked at a few headless CMS services: Sanity, Prismic, and Contentful. I chose Contentful, for now, as a data source of my personal journal. Prismic looks nice.

Used CSS grid for the first time: repeat(), minmax(), fr.

Collapsible Header

Tried to implement Airbnb-style collapsible header using Reanimated.

Responsive mobile menu

Implemented responsive mobile menu using Framer Motion.

diffClamp is cool

Learned what diffClamp does.

Post identicon

Added identicon to post preview.

Squigling line on hover

Added squigling hover effect.

Simple physics with Reanimated

Read Krzysztof Magiera’s ⟨Simple physics with Reanimated⟩. Seems like EPS constant, 1e-3, causes a problem: A few seconds of rest results in a jump on next drag. Otherwise, it is an awesome tutorial.

Learning react-native-reanimated

Trying to figure out how to use Reanimated. It’s more trickier than I expected to think about animation declaratively.

Newsletter seems like a good idea for blog marketting. Created an account at mailchimp, which has a free plan.

Configured now.json so that apex domain redirects to subdomain (www). Followed Now guide, but didn’t work. It said “Too many redirects”.

React Native Project

Initialized an Expo (React Native) project to build a mobile application.

Looks like Haptic API is now async: Haptic.selectionAsync().

robots.txt

Disallowing crawling via robots.txt prevents indexing, which is valuable for search engines to know if webpages are indexable.

Used an environment variable on Gatsby UI by setting it as site metadata on config file.

Initialized React Native project

Hot reloading doesn't work with a function component.

pointer-events

pointer-events is such a critical property for mobile UX.

Dupliacte content issue with ZEIT Now

ZEIT Now's preview deploy is helpful, but it comes with a price of duplicate contents issue.

Lockfiles

Read about lock files. Experimented with npm and Yarn.

yarn.lock, which is in YAML-like format, is more easier for human to read than package-lock.json, especially when reviewing diff.

Allow markdown comments on dhk.party

Added Markdown support in comment. Tried to let Staticman generate frontmatter files and read them using gatsby-plugin-mdx. Used react-markdown instead since jsx in comment felt wrong.

Configure 404 page, domain(dhk.party) and DNS

Enabled custom 404 page on ZEIT Now via routes field in now.json file.

Connected dhk.party to this website and created DNS alias record so that root(@) domain directs to the subdomain(www).

Self-hosted Staticman instance

Deployed Staticman instance via ZEIT Now.

No excerpt for non-latin mdx content

gatsby-plugin-mdx does not extract excerpt from Hangul content.

Gatsby's whole layout rerenders

Header, which is a part of shared layout, is re-rendered on every page transition. Had to use gatsby-plugin-layout to improve UX.

First impression of Gatsby-built site

Having seen Gatsby-built site in production, I was impressed by its performance (speed and responsiveness), though I chose it because React at first. It does not only serve static files, but also provide optimized SPA experience.

Start a personal blog for a great good

Started building a personal blog using Gatsby. The idea of sourcing data from anywhere is very cool, though GraphQL feels a tiny bit intimidating.

  • Data source – Github or Wordpress
  • Hosting – Netlify or ZEIT Now

Devlog