How I Started a Website

I’m trying to make a new website, and this will be the first in a series of DevLogs about my development process as I build this website.

Video version of this post

The idea of the website came from the need to store information that isn’t necessarily deserving of an entire blog post. These posts cover some of the things that I’m currently doing as well as some fundamentals of software development.

The tentative name is reference.bayanbennett.com and will serve as an ever-evolving repository of information. Whenever I’m referencing things, I can point to reference.bayanbennett.com and the page could contain interactive examples, information, and links to other resources. Of course, the site hasn’t been built yet, so the future is still uncertain.

Starting from an Example Project

I decided to start with a Next.js project with Material UI and TypeScript. Here’s the source: https://github.com/mui-org/material-ui/tree/next/examples/nextjs-with-typescript. As I have not built a production site using Next.js, I’m going to be making little mistakes and learning a lot.

The only thing that is different about this project and the Material UI template is that I've emptied index.tsx.

import React from "react";

const IndexPage = () => <>Heh</>;

export default IndexPage;

I’ve also included a layout component in _app.tsx. Note: the + simply denotes that the line has been added.

+ import { Layout } from "../layout";/* rest of file is the same */<ThemeProvider theme={theme}>
<CssBaseline />
+ <Layout>
<Component {...pageProps} />
+ </Layout>
</ThemeProvider>

The layout.tsx file simply is as follows:

import React from "react";
import { AppBar, Container, Toolbar, Typography } from "@material-ui/core";

export const Layout: React.FunctionComponent = ({ children }) => (
<>
<AppBar position="sticky">
<Toolbar>
<Typography variant="h6">Reference</Typography>
</Toolbar>
</AppBar>
<Container>{children}</Container>
</>
);

Proof of Concept for Interactive Examples

I wanted to have an interactive console window that would have example code in it that the user could run, see the results on the page, and modify to their liking. The examples could also include tests, using console.assert, that the user could run and see the results. There is an overwhelming number of possibilities, but the goal is that a visitor could, at a glimpse, explore a concept on a dedicated page.

For example, I have a post about exponential back-off and retries. The page goes through the code and it lists all the code, but there is no interactivity. Sites like CodeSandbox, JSFiddle, StackBlitz, and CodePen are fantastic resources, but with much more extensive feature sets than what I have in mind. A better comparison would be with the TensorFlowJS documentation, where the user can quickly run code samples and see the output.

Creating a Page

First, we’ll need to create a page to show an interactive example for Strings in JavaScript.

/* src/JavaScript/String/index.tsx */import React from "react"const StringPage = () => <>This is the Strings Page</>export default StringPage

Designing a Code Editor Wireframe

MDN is one of the best resources for documentation about web technologies. I was inspired by their code editor that can be found on some of their pages. Take String.length for example: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length

For my own reference site, I wanted to have minimal interactive examples and not so much of the depth that MDN provides β€” I’m not trying to create an explanatory page.

After a few minutes of playing with a few options, I produced this preliminary layout:

Simple layout sketched in MS Paint

Of course, this is just the first pass at a wireframe. As I progress, the design will undoubtedly change.

Translating the Wireframe to Material UI Components

Since this is a new project, I decided to use Material UI v5, which is currently in its alpha phase. The hope is, by the time that my site is ready, Material UI v5 will also be ready and I don’t have to migrate from v4 ➑ v5. The main drawback of this choice is dealing with bugs and breaking changes.

The layout is housed in the <Container> component, which limits its width via the maxWidth attribute. See: https://next.material-ui.com/api/container/

Material UI’s basic layout component is the <Box> (the same as a <div>): https://next.material-ui.com/components/box/. Here’s what the wireframe looks like implemented with the <Box> component.

import React from "react";
import { Box, Fab } from "@material-ui/core";
import { PlayArrow } from "@material-ui/icons";

const fabStyle = {
position: "absolute",
bottom: 0,
right: 0,
};

const StringPage = () => {
/* Some stuff will go here later */
return (
<>
<Box sx={{ display: "flex", flexDirection: "row" }}>
<Box sx={{ position: "relative", flex: 2 }}>
<textarea />
<Fab size="small" sx={fabStyle}>
<PlayArrow />
</Fab>
</Box>
<Box sx={{ flex: 1, backgroundColor: "rgba(0,0,0,0.1)" }}>{result}</Box>
</Box>
</>
);
};

Evaluating Code

At first, I used React.setState and onChange on the <textarea> tag. A handleChange function would evaluate the code and save it to the state. However, this meant that code was evaluated on every keypress. When the user would type in β€œc” to begin typing β€œconst”, the eval function would throw an error.

The wireframe included a button to evaluate code, so I quickly corrected this oversight and used the onClick attribute on the <Fab> component instead. This also meant that I could use an uncontrolled <textarea>. To read the value of the <textarea> I could use React.useRef and pass it to the <textarea> via the ref attribute.

Here’s the result:

import React from "react";
import { Box, Fab } from "@material-ui/core";
import { PlayArrow } from "@material-ui/icons";

const fabStyle = {
position: "absolute",
bottom: 0,
right: 0,
};

const StringPage = () => {
const [result, setResult] = React.useState("");
const codeRef = React.useRef<HTMLTextAreaElement>(null);
const evaluateCode = () => {
if (codeRef.current === null) return;
const code = codeRef.current.value;
if (code.length === 0) return;
try {
setResult(eval(code));
} catch (e) {
console.warn(e);
}
};
return (
<>
<Box sx={{ display: "flex", flexDirection: "row" }}>
<Box sx={{ position: "relative", flex: 2 }}>
<textarea ref={codeRef} />
<Fab size="small" sx={fabStyle} onClick={evaluateCode}>
<PlayArrow />
</Fab>
</Box>
<Box sx={{ flex: 1, backgroundColor: "rgba(0,0,0,0.1)" }}>{result}</Box>
</Box>
</>
);
};

export default StringPage;

Here’s an example:

Example input
The output of the example in the console (button pressed 3 times)

TL;DR

In this post, we took a quick look at how I started a simple project from some example code and created a proof-of-concept. The idea is to create a website that I can use to create interactive reference pages. These pages should have code samples that can be executed by the user. In the end, I was able to create a short function that evaluates the given code. The next step is UX/UI refinements, which include displaying the result on the page.

Weekly Webtips

Explore the world of web technologies through a series of tutorials

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer β€” welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store