Here is the fastest way to create a Next.js React app with TypeScript. For the step-by-step version, take a look at the longer version.
Let's use npx and create-next-app
.
npx \
create-next-app nextjs-app \
--use-npm \
--example \
"https://github.com/nonoesp/next-learn/tree/master/basics/typescript-final"
# Enter the app's directory
cd nextjs-app
# Run the app in development
npm run dev
# ready - started server on 0.0.0.0:3000, url: http://localhost:3000
You should be able to access the site at http://localhost:3000.
npm run build
npm start
# ready - started server on 0.0.0.0:3000, url: http://localhost:3000
You can watch my step-by-step video on How to build a Next.js app with React & TypeScript.
Here are the simplified steps to create a Next.js React app and add TypeScript to the mix. This tutorial combines my Create a Next.js app and Add TypeScript to Next.js posts.
Let's use npx and create-next-app
.
npx \
create-next-app nextjs-app \
--use-npm \
--example \
"https://github.com/vercel/next-learn/tree/master/basics/learn-starter"
# Enter your app's directory
cd nextjs-app
# Create an empty TypeScript configuration file
touch tsconfig.json
# Install TypeScript, React Types, and Node Types
npm install --save-dev typescript @types/react @types/node
You can customize your TypeScript in tsconfig.json
.
npm run dev
# ready - started server on 0.0.0.0:3000, url: http://localhost:3000
You should be able to access the site at http://localhost:3000.
npm run build
npm start
# ready - started server on 0.0.0.0:3000, url: http://localhost:3000
index.js
into index.tsx
Your application is now ready to be written in TypeScript. The example we've used only has one file named index.js
. Rename it to index.tsx
and re-write the JavaScript code (and any new code you add to the app) in TypeScript.
You can watch my step-by-step video on How to build a Next.js app with React & TypeScript.
Here are the steps to add TypeScript to your Next.js React application.
I assume you have a Next.js React application that can run in development mode. If that's not the case, Create a Next.js app first.
# Enter the directory of your app
cd nextjs-app
# Run Next.js in development
npm run dev
# ready - started server on 0.0.0.0:3000, url: http://localhost:3000
If you can access your site at http://localhost:3000, you're good to go.
tsconfig.json
file# Create an empty TypeScript configuration file
touch tsconfig.json
Simply by creating a tsconfig.json
file and restarting the application, Next.js will warn us that we're trying to work with TypeScript and have to install a set of required dependencies.
# Stop the running app with `CMD + C` (or `CTRL + C` on Windows)
# Run Next.js in development once again
npm run dev
You should receive the following warning when restarting the app.
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
It looks like you're trying to use TypeScript but do not have
the required package(s) installed.
Please install typescript, @types/react, and @types/node by running:
npm install --save-dev typescript @types/react @types/node
If you are not trying to use TypeScript, please remove the
tsconfig.json file from your package root (and any TypeScript
files in your pages directory).
npm install --save-dev typescript @types/react @types/node
npm run dev
# ready - started server on 0.0.0.0:3000, url: http://localhost:3000
# We detected TypeScript in your project and created a tsconfig.json
# file for you.
Note that Next.js detected the tsconfig.json
file, verified our dependencies were installed, and then populated our empty TypeScript configuration file with a boilerplate JSON object.
// tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"incremental": true,
"esModuleInterop": true,
"module": "esnext",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve"
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx"
],
"exclude": [
"node_modules"
]
}
index.js
into index.tsx
Your application is now ready to be written in TypeScript. The example we've used only has one file named index.js
. Rename it to index.tsx
and re-write the JavaScript code (and any new code you add to the app) in TypeScript.
If you want to learn more, you can watch my video on How to build a Next.js app with React & TypeScript and take a look at Next.js's official TypeScript tutorial.
As the official Create a Next.js App tutorial says, "there are many important details you need to consider to build a complete web application with React from scratch," but here I'm trying to get started as fast as possible.
Let's use npx and create-next-app
.
npx \
create-next-app nextjs-app \
--use-npm \
--example \
"https://github.com/vercel/next-learn/tree/master/basics/learn-starter"
Your fresh Next.js app is now in the nextjs-app
directory.
Now enter the directory and run the app in development mode.
cd nextjs-app
npm run dev
# ready - started server on 0.0.0.0:3000, url: http://localhost:3000
You should be able to access the site at http://localhost:3000.
npm run build
npm start
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
If you want to use TypeScript instead of JavaScript on your Next.js React app, read how to Add TypeScript to Next.js. I also have a step-by-step video on How to build a Next.js app with React & TypeScript.
I'm writing a series of posts on how to create a Next.js React app with and without TypeScript, trying to summarize the required steps.
# Create a Next.js React JavaScript app with npx
npx \
create-next-app nextjs-app \
--use-npm \
--example \
"https://github.com/nonoesp/next-learn/tree/master/basics/learn-starter"
# Enter the app's directory
cd nextjs-app
# Start the app in development mode
npm run dev
# > dev
# > next dev
#
# ready - started server on 0.0.0.0:3000, url: http://localhost:3000
# wait - compiling...
# event - compiled client and server successfully in 944 ms (113 modules)
You should be able to access the site at http://localhost:3000. =)
My site parses Markdown posts into HTML and code blocks are syntax-highlighted with the highlight.js JavaScript library.
In a nutshell, Markdown code blocks—the content between a pair of three backticks—are parsed into <pre><code>
HTML blocks.
If we take this Markdown input.
```
console.log(`Hello, highlight.js!`);
console.log(`Formatting Markdown code blocks!`);
const add = (a: number, b: number) => a + b
add(2, 3) // Returns 5
```
The Markdown parser converts it into a <pre><code>
HTML block.
<pre><code>console.log(`Hello, highlight.js!`);
console.log(`Formatting Markdown code blocks!`);
const add = (a: number, b: number) => a + b
add(2, 3) // Returns 5
</code></pre>
Which is then highlighted by highlight.js.
console.log(`Hello, highlight.js!`);
console.log(`Formatting Markdown code blocks!`);
const add = (a: number, b: number) => a + b
add(2, 3) // Returns 5
This is all the HTML code you really need.
highlight.js
highlight.js
CSS stylehighlight.js
<!-- Code block -->
<pre><code>console.log(`Hello, highlight.js!`);
console.log(`Formatting Markdown code blocks!`);
const add = (a: number, b: number) => a + b
add(2, 3) // Returns 5
</code></pre>
<!-- Load highlight.js from a CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.0/highlight.min.js"></script>
<!-- Optionally load a template from a CDN -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.0/styles/atom-one-light.min.css" integrity="sha512-o5v54Kh5PH0dgnf9ei0L+vMRsbm5fvIvnR/XkrZZjN4mqdaeH7PW66tumBoQVIaKNVrLCZiBEfHzRY4JJSMK/Q==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<!-- Initialize highlight.js -->
<script>hljs.initHighlightingOnLoad();</script>
In my case, I create custom templates or use the ones provided by highlight.js
. The only tweak to support the system's appearance—light and dark mode—is to use CSS's prefers-color-scheme
to target whether the user has the system's dark mode enabled.
/* highligh-styles.js */
/* Light mode highlight.js theme goes here */
@media screen and (prefers-color-scheme: dark) {
/* Dark mode highlight.js theme goes here */
}
Thanks to Nino. This post is a reply to his question on Twitter.
If you multiple Vue components of the same type throughout your application but they're not in the same parent DOM element, mounting them may not be as easy as calling their parent.
In this first example, we can mount all of our button-counter
components by mounting their parent, #button-container
.
<div id="button-container">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
We just need to make one call.
new Vue({ el: '#button-container' });
But what if our components are spread throughout different HTML elements?
Imagine you have components of the same (or different) types spread throughout your website's DOM.
<div>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
<div>
<button-counter></button-counter>
</div>
<button-counter></button-counter>
We can iterate through the DOM elements and mount them one by one.
// Obtain all button-counter elements
let elements = document.getElementsByTagName('button-counter');
// Convert HTMLCollection to array
let arr = Array.prototype.slice.call( elements )
// Loop through array and mount all elements
arr.forEach((el) => {
new Vue( { el });
});
Note that we had to convert the HTMLCollection
to a JavaScript array before we could call the .forEach()
function to iterate over the button-counter
host DOM nodes.
This works with Vue 2, and Vue 3 recently released new features for multi-root components and optional TypeScript support.
Change this.
window.Vue = require('vue');
For this.
window.Vue = require('vue').default;
Then this should work.
window.Vue = require('vue').default;
window.VueResource = require('vue-resource');
window.Vue.use(window.VueResource);
Pretty impressed by ImgIX's JSON format. Long story short, it provides a JSON metadata file for each resource you are serving via ImgIX (say, an image or a video) as in the example below just by appending fm=json
to any image request.
For this image.
https://nono.imgix.net/img/u/profile-nono-ma.jpg
You'd load the JSON at.
https://nono.imgix.net/img/u/profile-nono-ma.jpg?fm=json
What's nice is that with the imgix.js JavaScript library you can fetch the JSON file for each picture and—before loading any image data—decide how to deliver the image. In this CodePen provided by ImgIX, they crop a set of images to fit a certain aspect ratio (which ends up saving data as they cropped bits of each image are never loaded) avoiding also having to play with image background CSS tricks in order to fit an image to a given aspect ratio (as the image already has it!).
{
"Exif": {
"PixelXDimension": 1500,
"DateTimeDigitized": "2019:11:20 10:43:28",
"PixelYDimension": 1500,
"ColorSpace": 65535
},
"Orientation": 1,
"Output": {},
"Content-Type": "image\/jpeg",
"JFIF": {
"IsProgressive": true
},
"DPIWidth": 144,
"Content-Length": "180595",
"Depth": 8,
"ColorModel": "RGB",
"DPIHeight": 144,
"TIFF": {
"ResolutionUnit": 2,
"DateTime": "2019:11:20 11:17:40",
"Orientation": 1,
"Software": "Adobe Photoshop CC 2019 (Macintosh)",
"YResolution": 144,
"XResolution": 144
},
"PixelWidth": 1500,
"PixelHeight": 1500,
"ProfileName": "Display"
}
And here's the JavaScript included in that CodePen that does all the magic.
// Demonstrate the use of the `fm=json` parameter to resize images
// to a certain aspect ratio, using ES6.
let ratio = 16 / 9;
let maxSize = 300;
let placeImages = function () {
jQuery('.imgix-item').each((i, value) => {
let $elem = jQuery(value);
// We pull down the image specific by the 'data-src' attribute
// of each .imgix-item, but append the "?fm=json" query string to it.
// This instructs imgix to return the JSON Output Format instead of
// a manipulated image.
let url = new imgix.URL($elem.attr('data-src'), { fm: "json" }).getUrl();
jQuery.ajax(url).success((data) => {
let newWidth, newHeight;
// Next, we compute the new height/width params for
// each of our images.
if (data.PixelHeight > data.PixelWidth) {
newHeight = maxSize;
newWidth = Math.ceil(newHeight / ratio);
} else {
newWidth = maxSize;
newHeight = Math.ceil(newWidth / ratio);
}
// Now, we apply these to our actual images, setting the 'src'
// attribute for the first time.
$elem.get(0).src = new imgix.URL($elem.attr('data-src'), {
w: newWidth,
h: newHeight,
fit: "crop"
}).getUrl();
})
});
}
jQuery(document).ready(placeImages);
Microsoft recently open sourced, twenty five days ago, Maker.js — a JavaScript library to create drawings on the browser for CNC and laser cutting.
I love the playground site they made to share parametric scripts (say, of a smiley face, a hello, world text, a floor plan, and more). See all demos.
From their website:
- Drawings are a simple JavaScript object which can be serialized / deserialized conventionally with JSON. This also makes a drawing easy to clone.
- Other people's Models can be required the Node.s way, modified, and re-exported.
- Models can be scaled, distorted, measured, and converted to different unit systems.
- Paths can be distorted.
- Models can be rotated or mirrored.
- Find intersection points or intersection angles of paths.
- Traverse a model tree to reason over its children.
- Detect chains formed by paths connecting end to end.
- Get the points along a path or along a chain of paths.
- Easily add a curvature at the joint between any 2 paths, using a traditional or a dogbone fillet.
- Combine models with boolean operations to get unions, intersections, or punches.
- Expand paths to simulate a stroke thickness, with the option to bevel joints.
- Outline model to create a surrounding outline, with the option to bevel joints.
- Layout clones into rows, columns, grids, bricks, or honeycombs.
Via @alfarok's GitHub stars.