Skip to content

Commit 9a088bd

Browse files
kamalkamal
authored andcommitted
Init project
0 parents  commit 9a088bd

27 files changed

+6485
-0
lines changed

.gitignore

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# next.js
12+
/.next/
13+
/out/
14+
15+
# production
16+
/build
17+
18+
# misc
19+
.DS_Store
20+
*.pem
21+
22+
# debug
23+
npm-debug.log*
24+
yarn-debug.log*
25+
yarn-error.log*
26+
27+
# local env files
28+
.env.local
29+
.env.development.local
30+
.env.test.local
31+
.env.production.local
32+
33+
# vercel
34+
.vercel

README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# TypeScript Next.js example
2+
3+
This is a really simple project that shows the usage of Next.js with TypeScript.
4+
5+
## Deploy your own
6+
7+
Deploy the example using [Vercel](https://vercel.com):
8+
9+
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/vercel/next.js/tree/canary/examples/with-typescript)
10+
11+
## How to use it?
12+
13+
### Using `create-next-app`
14+
15+
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
16+
17+
```bash
18+
npx create-next-app --example with-typescript with-typescript-app
19+
# or
20+
yarn create next-app --example with-typescript with-typescript-app
21+
```
22+
23+
### Download manually
24+
25+
Download the example:
26+
27+
```bash
28+
curl https://codeload.github.com/vercel/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-typescript
29+
cd with-typescript
30+
```
31+
32+
Install it and run:
33+
34+
```bash
35+
npm install
36+
npm run dev
37+
# or
38+
yarn
39+
yarn dev
40+
```
41+
42+
Deploy it to the cloud with [Vercel](https://vercel.com/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
43+
44+
## Notes
45+
46+
This example shows how to integrate the TypeScript type system into Next.js. Since TypeScript is supported out of the box with Next.js, all we have to do is to install TypeScript.
47+
48+
```
49+
npm install --save-dev typescript
50+
```
51+
52+
To enable TypeScript's features, we install the type declarations for React and Node.
53+
54+
```
55+
npm install --save-dev @types/react @types/react-dom @types/node
56+
```
57+
58+
When we run `next dev` the next time, Next.js will start looking for any `.ts` or `.tsx` files in our project and builds it. It even automatically creates a `tsconfig.json` file for our project with the recommended settings.
59+
60+
Next.js has built-in TypeScript declarations, so we'll get autocompletion for Next.js' modules straight away.
61+
62+
A `type-check` script is also added to `package.json`, which runs TypeScript's `tsc` CLI in `noEmit` mode to run type-checking separately. You can then include this, for example, in your `test` scripts.

components/Layout.tsx

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import React, { ReactNode } from "react";
2+
import Link from "next/link";
3+
import Head from "next/head";
4+
5+
type Props = {
6+
children?: ReactNode;
7+
title?: string;
8+
};
9+
10+
const Layout = ({ children, title = "This is the default title" }: Props) => (
11+
<div>
12+
<Head>
13+
<title>{title}</title>
14+
<meta charSet="utf-8" />
15+
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
16+
</Head>
17+
<header>
18+
<nav>
19+
<Link href="/">
20+
<a>Home</a>
21+
</Link>{" "}
22+
|{" "}
23+
<Link href="/about">
24+
<a>About</a>
25+
</Link>{" "}
26+
|{" "}
27+
<Link href="/users">
28+
<a>Users List</a>
29+
</Link>{" "}
30+
|{" "}
31+
<Link href="/photos">
32+
<a>Photos List</a>
33+
</Link>{" "}
34+
| <a href="/api/users">Users API</a>
35+
</nav>
36+
</header>
37+
{children}
38+
<footer>
39+
<hr />
40+
<span>I'm here to stay (Footer)</span>
41+
</footer>
42+
</div>
43+
);
44+
45+
export default Layout;

components/List.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import * as React from 'react'
2+
import ListItem from './ListItem'
3+
import { User } from '../interfaces'
4+
5+
type Props = {
6+
items: User[]
7+
}
8+
9+
const List = ({ items }: Props) => (
10+
<ul>
11+
{items.map((item) => (
12+
<li key={item.id}>
13+
<ListItem data={item} />
14+
</li>
15+
))}
16+
</ul>
17+
)
18+
19+
export default List

components/ListDetail.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import * as React from 'react'
2+
3+
import { User } from '../interfaces'
4+
5+
type ListDetailProps = {
6+
item: User
7+
}
8+
9+
const ListDetail = ({ item: user }: ListDetailProps) => (
10+
<div>
11+
<h1>Detail for {user.name}</h1>
12+
<p>ID: {user.id}</p>
13+
</div>
14+
)
15+
16+
export default ListDetail

components/ListItem.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import React from 'react'
2+
import Link from 'next/link'
3+
4+
import { User } from '../interfaces'
5+
6+
type Props = {
7+
data: User
8+
}
9+
10+
const ListItem = ({ data }: Props) => (
11+
<Link href="/users/[id]" as={`/users/${data.id}`}>
12+
<a>
13+
{data.id}: {data.name}
14+
</a>
15+
</Link>
16+
)
17+
18+
export default ListItem

interfaces/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// You can include shared interfaces/types in a separate file
2+
// and then use them in any component by importing them. For
3+
// example, to import the interface below do:
4+
//
5+
// import User from 'path/to/interfaces';
6+
7+
export type User = {
8+
id: number
9+
name: string
10+
}

next-env.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/// <reference types="next" />
2+
/// <reference types="next/types/global" />

next.config.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
module.exports = {
2+
// basePath: "/about",
3+
// async rewrites() {
4+
// return [
5+
// {
6+
// source: "/about",
7+
// destination: "/",
8+
// },
9+
// ];
10+
// },
11+
// async redirects() {
12+
// return [
13+
// {
14+
// source: "/about",
15+
// destination: "/",
16+
// permanent: true,
17+
// },
18+
// ];
19+
// },
20+
};
21+
22+
console.log("next config");

package.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "with-typescript",
3+
"version": "1.0.0",
4+
"scripts": {
5+
"dev": "next",
6+
"build": "next build",
7+
"start": "next start",
8+
"type-check": "tsc"
9+
},
10+
"dependencies": {
11+
"next": "latest",
12+
"next-redux-wrapper": "^6.0.2",
13+
"nprogress": "^0.2.0",
14+
"react": "^16.12.0",
15+
"react-dom": "^16.12.0",
16+
"react-redux": "^7.2.1",
17+
"redux": "^4.0.5",
18+
"redux-logger": "^3.0.6",
19+
"redux-thunk": "^2.3.0"
20+
},
21+
"devDependencies": {
22+
"@types/node": "^12.12.21",
23+
"@types/react": "^16.9.16",
24+
"@types/react-dom": "^16.9.4",
25+
"@types/react-redux": "^7.1.9",
26+
"@types/redux-logger": "^3.0.8",
27+
"redux-devtools-extension": "^2.13.8",
28+
"typescript": "3.7.3"
29+
},
30+
"license": "ISC"
31+
}

pages/_app.tsx

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import App, { AppProps, AppContext } from "next/app";
2+
3+
// Progress.
4+
import Router from "next/router";
5+
import NProgress from "nprogress"; //nprogress module
6+
import "nprogress/nprogress.css"; //styles of nprogress
7+
//Binding events.
8+
Router.events.on("routeChangeStart", () => NProgress.start());
9+
Router.events.on("routeChangeComplete", () => NProgress.done());
10+
Router.events.on("routeChangeError", () => NProgress.done());
11+
12+
// Redux.
13+
import { createStore, applyMiddleware } from "redux";
14+
import { createLogger } from "redux-logger";
15+
import { HYDRATE, createWrapper } from "next-redux-wrapper";
16+
import thunkMiddleware from "redux-thunk";
17+
// Store.
18+
import combinedReducer from "../redux/reducers/rootReducer";
19+
20+
// Component App.
21+
function MyApp({ Component, pageProps }: AppProps) {
22+
return <Component {...pageProps} />;
23+
}
24+
25+
// Middleware.
26+
const bindMiddleware = (middleware: any) => {
27+
if (process.env.NODE_ENV !== "production") {
28+
const { composeWithDevTools } = require("redux-devtools-extension");
29+
// Create loggerMiddleware.
30+
const loggerMiddleware = createLogger();
31+
return composeWithDevTools(
32+
applyMiddleware(...middleware, loggerMiddleware)
33+
);
34+
}
35+
return applyMiddleware(...middleware);
36+
};
37+
38+
// Reducer.
39+
const reducer = (state: any, action: any) => {
40+
if (action.type === HYDRATE) {
41+
const nextState = {
42+
...state,
43+
...action.payload,
44+
};
45+
return nextState;
46+
} else {
47+
return combinedReducer(state, action);
48+
}
49+
};
50+
51+
// Init store.
52+
const initStore = () => {
53+
return createStore(reducer, bindMiddleware([thunkMiddleware]));
54+
};
55+
56+
// Create a wrapper.
57+
const wrapper = createWrapper(initStore);
58+
59+
// Create Initial Props.
60+
MyApp.getInitialProps = async (appContext: AppContext) => {
61+
const appProps = await App.getInitialProps(appContext);
62+
return { ...appProps };
63+
};
64+
65+
export default wrapper.withRedux(MyApp);

pages/about.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { connect } from "react-redux";
2+
import { bindActionCreators } from "redux";
3+
import {
4+
decrementCounter,
5+
incrementCounter,
6+
} from "../redux/actions/counterActions";
7+
8+
import Link from "next/link";
9+
import Layout from "../components/Layout";
10+
11+
const IndexPage = (props: any) => {
12+
return (
13+
<Layout title="About | Next.js + TypeScript Example">
14+
<div>
15+
<h1>About page</h1>
16+
<h2>{props.counter}</h2>
17+
</div>
18+
<hr />
19+
{props.photos.length > 0 ? JSON.stringify(props.photos) : <></>}
20+
<hr />
21+
<Link href="/">
22+
<a>Go home</a>
23+
</Link>
24+
</Layout>
25+
);
26+
};
27+
28+
const mapDispatchToProps = (dispatch: any) => {
29+
return {
30+
incrementCounter: bindActionCreators(incrementCounter, dispatch),
31+
decrementCounter: bindActionCreators(decrementCounter, dispatch),
32+
};
33+
};
34+
35+
const mapStateToProps = (state: any) => ({
36+
counter: state.counter.value,
37+
photos: state.photo.photos,
38+
});
39+
40+
export default connect(mapStateToProps, mapDispatchToProps)(IndexPage);

pages/api/users/index.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { NextApiRequest, NextApiResponse } from 'next'
2+
import { sampleUserData } from '../../../utils/sample-data'
3+
4+
const handler = (_req: NextApiRequest, res: NextApiResponse) => {
5+
try {
6+
if (!Array.isArray(sampleUserData)) {
7+
throw new Error('Cannot find user data')
8+
}
9+
10+
res.status(200).json(sampleUserData)
11+
} catch (err) {
12+
res.status(500).json({ statusCode: 500, message: err.message })
13+
}
14+
}
15+
16+
export default handler

0 commit comments

Comments
 (0)