Skip to content

Commit cb92b88

Browse files
committed
a basic next.js template
1 parent 89007d3 commit cb92b88

File tree

12 files changed

+681
-1
lines changed

12 files changed

+681
-1
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
# next.js-example-template
1+
# next.js-example-template
2+
3+
next.js site template that maps optimizes static assets and serves favicons, Dockerfile included.

components/Container.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import Link from 'next/link'
2+
import Head from 'next/head'
3+
4+
export default ({ children, id, className }) => (
5+
<div className={`content-container ${className}`} id={id}>
6+
<div className="sleeve">
7+
{ children }
8+
</div>
9+
</div>
10+
)

components/MarkdownText.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
'use strict';
2+
3+
import React from 'react';
4+
import Markdown from 'remarkable';
5+
import Link from 'next/prefetch'
6+
7+
8+
9+
var Remarkable = React.createClass({
10+
11+
getDefaultProps() {
12+
return {
13+
container: 'div',
14+
options: {}
15+
};
16+
}
17+
18+
render() {
19+
20+
var Container = this.props.container;
21+
22+
return (
23+
<Container>
24+
{this.content()}
25+
</Container>
26+
);
27+
}
28+
29+
componentWillUpdate(nextProps, nextState) {
30+
if (nextProps.options !== this.props.options) {
31+
this.md = new Markdown(nextProps.options);
32+
}
33+
}
34+
35+
content() {
36+
37+
if (this.props.source) {
38+
return <span id={this.props.id} dangerouslySetInnerHTML={{ __html: this.renderMarkdown(this.props.source) }} />;
39+
}
40+
else {
41+
return React.Children.map(this.props.children, child => {
42+
if (typeof child === 'string') {
43+
44+
return <span id={this.props.id} dangerouslySetInnerHTML={{ __html: this.renderMarkdown(child) }} />;
45+
}
46+
else {
47+
return child;
48+
}
49+
});
50+
}
51+
}
52+
53+
renderMarkdown(source) {
54+
55+
if (!this.md) {
56+
this.md = new Markdown(this.props.options);
57+
}
58+
59+
let sourcetomodify = source;
60+
61+
let regexpattern = "<a href\=(\"|\')((https?:\/\/" + encodeURIComponent() + '|\.\.|\.|\/).+\/?)(\"|\')>([^"]+)<\/a>';
62+
63+
let sourcemodified = sourcetomodify.replace(new RegExp(regexpattern, "gm"), "<Link to=$2>$5<\/Link>" );
64+
65+
return this.md.render(source);
66+
67+
}
68+
69+
});
70+
71+
export default Remarkable;

components/SVGIMG.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import React from 'react';
2+
3+
4+
const SVGIMG = React.createClass({
5+
render() {
6+
const SvgSrc = this.props.src;
7+
8+
return (
9+
<div dangerouslySetInnerHTML={{ __html: SvgSrc }} />
10+
)
11+
}
12+
})
13+
14+
export default SVGIMG

gulpfile.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const gulp = require('gulp');
2+
const imagemin = require('gulp-imagemin');
3+
var del = require('del');
4+
5+
var paths = {
6+
images: [ './static/**/*(*.jpg|*.svg|*.gif|*.png)', '!./static/o/**/*' ]
7+
, imagesoptimized: './static/o/'
8+
};
9+
10+
gulp.task('clean', function() {
11+
// You can use multiple globbing patterns as you would with `gulp.src`
12+
return del( paths.imagesoptimized );
13+
});
14+
15+
gulp.task('images', ['clean'], () =>
16+
gulp.src(paths.images)
17+
.pipe( imagemin({optimizationLevel: 5}) )
18+
.pipe( gulp.dest( paths.imagesoptimized ) )
19+
);
20+
21+
gulp.task('default', ['watch', 'scripts', 'images']);

next.config.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
module.exports = {
2+
webpack: (config, { dev }) => {
3+
config.module.rules.push(
4+
{
5+
test: /\.(css|scss|svg|jpg)/,
6+
loader: 'emit-file-loader',
7+
options: {
8+
name: 'dist/[path][name].[ext]'
9+
}
10+
}
11+
,
12+
{
13+
test: /\.(svg|jpg)$/,
14+
loader: 'babel-loader!raw-loader'
15+
}
16+
,
17+
{
18+
test: /\.css$/,
19+
loader: 'babel-loader!raw-loader!sass-loader'
20+
}
21+
,
22+
{
23+
test: /\.scss$/,
24+
loader: 'babel-loader!raw-loader!sass-loader'
25+
}
26+
)
27+
return config
28+
}
29+
}

package.json

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"name": "optimized",
3+
"version": "1.0.0",
4+
"description": "https://optimized.technology",
5+
"repository": "https://github.com/optimized/optimized.technology",
6+
"license": "GPLv3",
7+
"dependencies": {
8+
"babel-loader": "^6.3.2",
9+
"babel-plugin-wrap-in-js": "^1.1.0",
10+
"css-loader": "^0.26.1",
11+
"next": "^2.0.0-beta.31",
12+
"node-sass": "^4.4.0",
13+
"normalize.css": "^5.0.0",
14+
"raw-loader": "^0.5.1",
15+
"react": "^15.4.2",
16+
"react-dom": "^15.4.2",
17+
"react-markdown": "^2.4.4",
18+
"remarkable": "^1.7.1",
19+
"sass-loader": "^4.1.1",
20+
"webpack": "^2.2.1"
21+
},
22+
"devDependencies": {
23+
"del": "^2.2.2",
24+
"gulp": "^3.9.1",
25+
"gulp-imagemin": "^3.1.1",
26+
"now": "^4.5.6"
27+
},
28+
"scripts": {
29+
"dev": "node server.js",
30+
"build": "gulp images && next build",
31+
"start": "NODE_ENV=production node server.js"
32+
},
33+
"babel": {
34+
"plugins": [
35+
[
36+
"wrap-in-js",
37+
{
38+
"extensions": [
39+
"css$",
40+
"scss$",
41+
"jpg$",
42+
"svg$"
43+
]
44+
}
45+
]
46+
],
47+
"presets": [
48+
"next/babel"
49+
],
50+
"ignore": []
51+
}
52+
}

pages/_document.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React from 'react';
2+
import Document, { Head, Main, NextScript } from 'next/document';
3+
import normalize from '../node_modules/normalize.css/normalize.css';
4+
import stylesheet from './styles.scss';
5+
6+
export default class MyDocument extends Document {
7+
render() {
8+
return (
9+
<html>
10+
<Head>
11+
<meta name="viewport" content="initial-scale=1" />
12+
<style dangerouslySetInnerHTML={{ __html: normalize + stylesheet }} />
13+
</Head>
14+
<body>
15+
<Main />
16+
<NextScript />
17+
</body>
18+
</html>
19+
);
20+
}
21+
}

pages/index.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import React from 'react'
2+
import Link from 'next/prefetch'
3+
import SVGIMG from '../components/SVGIMG.js'
4+
import logo from '../static/logo.svg';
5+
import clientlogos from '../static/logos-clients.svg';
6+
import bg from '../static/header-background-gray.svg';
7+
import Markdown from '../components/MarkdownText.js';
8+
import Container from '../components/Container.js';
9+
10+
// If you are using `css-loader` with CSS modules,
11+
// `styles` would be an object containing the generated classnames
12+
13+
class MyComponent extends React.Component {
14+
static async getInitialProps({req}) {
15+
16+
return req
17+
? {
18+
userAgent: req.headers['user-agent']
19+
}
20+
: {
21+
userAgent: navigator.userAgent
22+
}
23+
}
24+
25+
render() {
26+
return (
27+
<main>
28+
<header id="header">
29+
30+
<SVGIMG src={bg} />
31+
32+
<div id="logo">
33+
34+
<SVGIMG src={logo} />
35+
<div id="description">
36+
<Markdown source='This is one sentence.' options={{
37+
html: true,
38+
linkify: true,
39+
typographer: true
40+
}}/>
41+
</div>
42+
</div>
43+
44+
</header>
45+
46+
<Container id="intro">
47+
<Markdown options={{
48+
html: true,
49+
linkify: true,
50+
typographer: true
51+
}}>
52+
This is a short paragraph.
53+
54+
This is also a short paragraph.
55+
</Markdown>
56+
</Container>
57+
58+
</main>
59+
);
60+
}
61+
}
62+
63+
export default MyComponent;

0 commit comments

Comments
 (0)