How I Started a Website

Using other people’s code

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.

--

--

𝐁𝐚𝐲𝐚𝐧 𝐁𝐞𝐧𝐧𝐞𝐭𝐭
Webtips
Writer for

My goal is to serve humanity and to bring happiness to others. I want to understand the problems around us and help find solutions. https://www.bayanbennett.com