├── .gitignore ├── README.md ├── package.json ├── public ├── favicon.ico └── index.html ├── src ├── App.js ├── App.test.js ├── components │ ├── Nav.js │ ├── NavLink.js │ ├── Page.js │ ├── Title.js │ └── Wrapper.js ├── index.css ├── index.js └── views │ ├── About.js │ ├── Home.js │ └── NoMatch.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | 6 | # testing 7 | coverage 8 | 9 | # production 10 | build 11 | 12 | # misc 13 | .DS_Store 14 | .env 15 | npm-debug.log 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![An Almost Static Stack](https://i.imgur.com/NStGYap.jpg) 2 | 3 | # An Almost Static Stack 4 | 5 | This repo serves as a companion to the [tutorial of the same name, over on Medium](https://medium.com/superhighfives/). 6 | 7 | ## Getting Started 8 | 9 | ``` shell 10 | git clone https://github.com/superhighfives/an-almost-static-stack.git 11 | cd an-almost-static-stack 12 | yarn install 13 | yarn start 14 | ``` 15 | 16 | Once you're ready to deploy to [Surge](https://surge.sh), run: 17 | 18 | ``` shell 19 | yarn deploy 20 | ``` 21 | 22 | Voila! 23 | 24 | If you're not into [Yarn](https://yarnpkg.com/), `npm install`, `npm start` and `npm run deploy` all work as well. 25 | 26 | ## Create React App 27 | 28 | This project was bootstrapped with [Create React App](https://github.com/facebookincubator/create-react-app). 29 | 30 | You can find more information [here](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md). 31 | 32 | ## Performance and Optimisations 33 | 34 | [@stereobooster](https://github.com/stereobooster) has put together a great run thorugh of possible performance optimisations and links to further reading here: https://github.com/stereobooster/react-snap/blob/master/doc/an-almost-static-stack-optimization.md 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "devDependencies": { 6 | "react-scripts": "1.0.17", 7 | "standard": "^10.0.3" 8 | }, 9 | "dependencies": { 10 | "react": "^16.1.1", 11 | "react-dom": "^16.1.1", 12 | "react-helmet": "^5.2.0", 13 | "react-router-dom": "^4.2.2", 14 | "react-scripts": "1.0.17", 15 | "react-snapshot": "^1.3.0", 16 | "styled-components": "^2.2.3" 17 | }, 18 | "scripts": { 19 | "start": "react-scripts start", 20 | "build": "react-scripts build && react-snapshot", 21 | "test": "react-scripts test --env=jsdom", 22 | "eject": "react-scripts eject", 23 | "deploy": "npm run build && surge -p build" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superhighfives/an-almost-static-stack/af9b20a428bc1860335e76bf6f9160584bee2a75/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 16 | React App 17 | 18 | 19 |
20 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { BrowserRouter as Router, Route, Switch } from 'react-router-dom' 3 | import Helmet from 'react-helmet' 4 | import Home from './views/Home' 5 | import About from './views/About' 6 | import NoMatch from './views/NoMatch' 7 | import Wrapper from './components/Wrapper' 8 | import Title from './components/Title' 9 | import Nav from './components/Nav' 10 | import NavLink from './components/NavLink' 11 | 12 | const title = 'You Are Doing Great' 13 | const routes = [ 14 | { 15 | title: 'Home', 16 | path: '/', 17 | component: Home, 18 | exact: true 19 | }, { 20 | title: 'About', 21 | path: '/about', 22 | component: About 23 | } 24 | ] 25 | 26 | class App extends Component { 27 | render () { 28 | return ( 29 | 30 | 31 | 32 | YADG 33 | 39 | 40 | {routes.map((route, i) => ( 41 | 42 | ))} 43 | 44 | 45 | 46 | 47 | ) 48 | } 49 | } 50 | 51 | export default App 52 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | }); 9 | -------------------------------------------------------------------------------- /src/components/Nav.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | 3 | export default styled.nav` 4 | padding: 1rem; 5 | background: #fff; 6 | border: 1px solid #e7e7e7; 7 | h1 { 8 | text-transform: uppercase; 9 | letter-spacing: 0.1em; 10 | font-size: 0.875rem; 11 | } 12 | > * { 13 | margin: 0 10px; 14 | display: inline-block; 15 | margin-top: 0; 16 | } 17 | ` 18 | -------------------------------------------------------------------------------- /src/components/NavLink.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Route, Link } from 'react-router-dom' 3 | import styled from 'styled-components' 4 | 5 | const NavLink = styled.div` 6 | a { 7 | transition: color 0.2s, border-bottom-color 0.2s; 8 | color: ${props => props.active ? '#0000ff' : '#666'}; 9 | text-decoration: none; 10 | border-bottom: 2px solid; 11 | border-bottom-color: ${props => props.active ? 'rgba(0, 0, 255, 0.1)' : 'transparent'}; 12 | &:hover, &:active, &:focus { 13 | color: ${props => props.active ? '#0000ff' : '#222'}; 14 | } 15 | } 16 | ` 17 | 18 | export default ({path, exact, ...props}) => ( 19 | ( 20 | 21 | {props.title} 22 | 23 | )} /> 24 | ) 25 | -------------------------------------------------------------------------------- /src/components/Page.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | 3 | export default styled.div` 4 | h1 { 5 | font-size: 5vmin; 6 | font-weight: normal; 7 | color: #0000ff; 8 | } 9 | p { 10 | font-size: 0.9375rem; 11 | } 12 | ` 13 | -------------------------------------------------------------------------------- /src/components/Title.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | 3 | export default styled.h1` 4 | font-size: 10vmin; 5 | line-height: 1em; 6 | font-weight: bold; 7 | ` 8 | -------------------------------------------------------------------------------- /src/components/Wrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | 3 | export default styled.div` 4 | padding: 4rem 1rem; 5 | margin: 0 auto; 6 | @media (min-width: 801px) { 7 | width: 80vw; 8 | } 9 | max-width: 1140px; 10 | ` 11 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: 'Arial', sans-serif; 5 | } 6 | 7 | *, 8 | *:before, 9 | *:after { 10 | box-sizing: border-box; 11 | } 12 | 13 | * { 14 | font-size: 1em; 15 | line-height: 1.4em; 16 | margin: 0; 17 | } 18 | 19 | * + * { 20 | margin-top: 1rem; 21 | } 22 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { render } from 'react-snapshot' 3 | import App from './App' 4 | import './index.css' 5 | 6 | const rootEl = document.getElementById('root') 7 | render(, rootEl) 8 | 9 | if (module.hot) { 10 | module.hot.accept('./App', () => { 11 | const NextApp = require('./App').default 12 | render(, rootEl) 13 | }) 14 | } 15 | -------------------------------------------------------------------------------- /src/views/About.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Helmet from 'react-helmet' 3 | import Page from '../components/Page' 4 | 5 | export default () => ( 6 | 7 |

This is the About view.

8 |

Ante himenaeos a vestibulum dignissim cursus porta a amet blandit massa netus parturient ac diam faucibus a vestibulum scelerisque dapibus ante vivamus praesent diam. Est duis dapibus parturient a a tristique duis adipiscing nam vivamus natoque habitasse suspendisse eu curabitur pretium scelerisque sodales consectetur est a augue conubia natoque penatibus ligula lacus. Parturient sagittis vulputate parturient urna ipsum aliquam suspendisse diam adipiscing at a massa urna maecenas litora inceptos pulvinar tempus odio pharetra mi platea nunc viverra. Parturient venenatis ipsum suspendisse ullamcorper nam himenaeos natoque sem auctor non et odio ridiculus elit volutpat vestibulum nisl a vestibulum libero cum molestie vestibulum. Condimentum sem magnis erat curae duis ut gravida parturient accumsan egestas a vestibulum suscipit a a at turpis varius sociis.

9 |

Quisque aliquet rhoncus est quisque torquent velit orci luctus consectetur pharetra consectetur ac proin cras a consequat scelerisque dictumst faucibus. Id condimentum consectetur gravida donec cursus duis a vehicula parturient volutpat euismod habitant litora vestibulum a ad vestibulum sed. Dui amet nam vestibulum ipsum consectetur dapibus eu tempus vel a nec proin ornare nibh. Nunc cras tristique a eu non nunc auctor phasellus nisi porttitor tempus ad sodales at. A parturient adipiscing non neque morbi felis libero taciti fusce quisque tortor a posuere augue diam placerat vestibulum varius montes suspendisse parturient id. Iaculis suspendisse consectetur vitae libero a lectus quisque enim vulputate adipiscing fames viverra gravida vestibulum ullamcorper.

10 |

Accumsan dui nullam id suspendisse vestibulum fames lobortis id sit vehicula pretium mus accumsan non volutpat mi. Ad orci ligula dis venenatis a maecenas tempor per nullam egestas vestibulum penatibus a suspendisse vel nulla tempus per scelerisque elit sed quisque sapien vestibulum ac cum enim a. Eleifend quam vestibulum diam suspendisse eu inceptos est iaculis in eros vestibulum velit class a massa diam potenti. Parturient ligula a diam integer nullam vestibulum platea ad donec a a inceptos ac cubilia condimentum habitant in ridiculus quisque sit. Duis sit mi augue leo adipiscing condimentum nostra a eu adipiscing sapien massa felis vestibulum senectus et taciti sodales.

11 |

Iaculis ac vestibulum ullamcorper parturient et dis a parturient congue enim ante nostra adipiscing lobortis a. Ullamcorper condimentum aliquet in commodo ligula velit himenaeos ad metus interdum eu fringilla mi vulputate eu platea sed integer. Gravida pulvinar per nisi fames nascetur ut metus ipsum leo scelerisque habitasse iaculis enim ad luctus molestie vestibulum a montes suspendisse nisi eget primis eleifend quisque dui parturient.

12 |

Cum class adipiscing aenean primis sed a ultricies himenaeos senectus bibendum interdum vel eleifend at justo. At ultricies posuere ullamcorper turpis praesent quam curae convallis suspendisse nullam parturient consequat sem condimentum rutrum eget. Luctus turpis facilisi potenti condimentum consectetur euismod ut in eu ac fringilla pulvinar a magna. Nisi gravida eu quisque egestas adipiscing adipiscing magna nam integer suspendisse et cubilia parturient nisl ut in suscipit a sit dapibus vestibulum nec condimentum a a. Eros libero ac quis vestibulum potenti lorem a a consectetur facilisis porta ultrices at sodales. Vestibulum adipiscing iaculis velit lacus mollis consectetur scelerisque mattis sapien parturient porta bibendum ultricies id urna ligula gravida curae facilisis.

13 |

A sem vel nec sodales mi vivamus senectus sed potenti a parturient nascetur tincidunt nisi pulvinar rhoncus a. Risus imperdiet taciti suspendisse facilisi a per metus cubilia varius a nostra adipiscing amet ultrices quisque ac mi a. Dictumst a ultrices mi a dignissim ad fermentum eget a nam et a blandit scelerisque. Taciti lorem tempor quam vestibulum dis habitasse vestibulum diam vel est ut proin dis auctor. Suscipit scelerisque orci magna interdum vel bibendum duis netus a consectetur dui magnis ac aliquet sem posuere tincidunt vestibulum.

14 | 15 |
16 | ) 17 | -------------------------------------------------------------------------------- /src/views/Home.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Helmet from 'react-helmet' 3 | import Page from '../components/Page' 4 | 5 | export default () => ( 6 | 7 |

This is the Home view.

8 |

Scelerisque venenatis nibh fames ad quam feugiat leo commodo vitae sed lacus duis habitant maecenas sem interdum quisque duis mauris scelerisque scelerisque dui elit a condimentum vestibulum ad vestibulum. Laoreet nostra dui vivamus vestibulum integer taciti suscipit consectetur in a nullam quam nam ad nunc class nec ullamcorper urna sed nascetur ad. Vestibulum a sem leo nunc condimentum vestibulum euismod sapien aenean adipiscing a mi volutpat non fames. Adipiscing parturient parturient sit nec viverra tristique dui senectus commodo sem eu vestibulum vestibulum lorem ullamcorper. A quis a volutpat posuere suspendisse commodo nec elit parturient parturient sit ac sed suspendisse nam ullamcorper. Sit in a ut vivamus fringilla penatibus suspendisse scelerisque eu bibendum a egestas sodales vel rhoncus phasellus suspendisse faucibus viverra ultricies fusce laoreet libero a taciti.

9 |

Elementum cras id suspendisse mi ut eros elit a enim curabitur posuere adipiscing eleifend auctor dictumst hac porttitor iaculis dis. Ut porttitor neque etiam primis et vestibulum parturient consectetur a etiam class consectetur a in massa parturient hac sed litora massa. Arcu enim arcu ac interdum ullamcorper consectetur aptent natoque curae mattis adipiscing a non metus netus arcu accumsan nam quisque condimentum posuere platea congue nisl mollis id nascetur.

10 |

Facilisis diam adipiscing ut eu porta cubilia donec scelerisque suspendisse suspendisse parturient a elit adipiscing in eu porttitor at suspendisse suspendisse placerat. Faucibus vestibulum habitasse ac dignissim a interdum fringilla nisi tortor eget dictum netus curae a pulvinar semper feugiat pharetra. Cras facilisis feugiat mi urna nec porttitor id leo suspendisse suspendisse phasellus parturient lacus lobortis condimentum a mus. Mi nam phasellus ridiculus est nisl nullam maecenas eu a erat proin facilisis at massa sit ac aenean tempus sed pharetra curabitur gravida nulla dapibus in. Dolor venenatis sit ullamcorper suspendisse eu ac ridiculus a adipiscing et a suscipit lectus turpis volutpat lectus tincidunt per rutrum vestibulum consectetur consectetur adipiscing quam.

11 |

Ullamcorper enim morbi adipiscing ac lacinia vestibulum tempor a pulvinar mauris natoque litora lectus a senectus. Parturient a sagittis viverra consectetur convallis in auctor dapibus vestibulum facilisi parturient ullamcorper vulputate a ullamcorper pulvinar justo platea fermentum aptent. Lectus condimentum vestibulum ut faucibus vulputate a feugiat aliquet faucibus platea iaculis sed condimentum vulputate scelerisque a eu in mi ullamcorper scelerisque adipiscing et fames parturient mollis adipiscing varius.

12 |

Donec et pulvinar mi elementum parturient penatibus id dui scelerisque adipiscing egestas urna pharetra praesent scelerisque. Ullamcorper quis hendrerit a elit mi sit dis vestibulum fringilla mi pulvinar in erat aptent vestibulum nisi a enim vestibulum parturient. Laoreet ad in aliquet magna accumsan donec fringilla tellus consectetur vulputate dui interdum nisl sociis aliquam sociis adipiscing quisque adipiscing et velit.

13 |

Sit vitae id ullamcorper adipiscing adipiscing nunc a vitae litora dolor consectetur primis parturient ligula. Sit porttitor luctus hac eu purus parturient phasellus ullamcorper eros hac malesuada aliquet suspendisse duis laoreet cum augue proin consectetur feugiat a scelerisque taciti ullamcorper parturient. Ut vel parturient parturient consectetur vel eros quisque tellus etiam parturient integer eleifend quisque condimentum faucibus congue nisi facilisi quam a pharetra viverra montes. Ad magna a curae turpis auctor condimentum nulla massa ligula himenaeos tempor a integer condimentum integer.

14 | 15 |
16 | ) 17 | -------------------------------------------------------------------------------- /src/views/NoMatch.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Helmet from 'react-helmet' 3 | import Page from '../components/Page' 4 | 5 | export default () => ( 6 | 7 |

404?!

8 | 9 |
10 | ) 11 | --------------------------------------------------------------------------------