Skip to content
This repository has been archived by the owner on May 10, 2021. It is now read-only.

Commit

Permalink
Add support for statically routed SSG pages
Browse files Browse the repository at this point in the history
Copy pre-rendered pages with SSG to Netlify publish directory and
copy SSG page JSON data to _next/data/ directory.

See: #7
  • Loading branch information
FinnWoelm committed Jun 1, 2020
1 parent 87e4057 commit 89295e8
Show file tree
Hide file tree
Showing 14 changed files with 461 additions and 214 deletions.
36 changes: 36 additions & 0 deletions cypress/fixtures/pages/getStaticProps/static.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Link from 'next/link'

const Show = ({ show }) => (
<div>
<p>
This page uses getStaticProps() to pre-fetch a TV show.
</p>

<hr/>

<h1>Show #{show.id}</h1>
<p>
{show.name}
</p>

<hr/>

<Link href="/">
<a>Go back home</a>
</Link>
</div>
)

export async function getStaticProps(context) {

const res = await fetch(`https://api.tvmaze.com/shows/71`);
const data = await res.json();

return {
props: {
show: data
}
}
}

export default Show
15 changes: 14 additions & 1 deletion cypress/fixtures/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,20 @@ const Index = ({ shows }) => (
</li>
</ul>

<h1>4. Static Pages Stay Static</h1>
<h1>4. getStaticProps? Yes!</h1>
<p>
next-on-netlify supports getStaticProps.
</p>

<ul>
<li>
<Link href="/getStaticProps/static">
<a>getStaticProps/static</a>
</Link>
</li>
</ul>

<h1>5. Static Pages Stay Static</h1>
<p>
next-on-netlify automatically determines which pages are dynamic and
which ones are static.
Expand Down
230 changes: 130 additions & 100 deletions cypress/integration/default_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,151 +52,181 @@ after(() => {
cy.task('clearDeployment')
})

describe('SSR page', () => {
it('loads TV shows', () => {
cy.visit('/')
describe('getInitialProps', () => {
context('with static route', () => {
it('loads TV shows', () => {
cy.visit('/')

cy.get('ul').first().children().should('have.length', 5)
})
cy.get('ul').first().children().should('have.length', 5)
})

it('loads TV shows when SSR-ing', () => {
cy.ssr('/')
it('loads TV shows when SSR-ing', () => {
cy.ssr('/')

cy.get('ul').first().children().should('have.length', 5)
cy.get('ul').first().children().should('have.length', 5)
})
})
})

describe('dynamic SSR page', () => {
it('loads TV show', () => {
cy.visit('/shows/24251')
context('with dynamic route', () => {
it('loads TV show', () => {
cy.visit('/shows/24251')

cy.get('h1').should('contain', 'Show #24251')
cy.get('p').should('contain', 'Animal Science')
})
cy.get('h1').should('contain', 'Show #24251')
cy.get('p').should('contain', 'Animal Science')
})

it('loads TV show when SSR-ing', () => {
cy.ssr('/shows/24251')
it('loads TV show when SSR-ing', () => {
cy.ssr('/shows/24251')

cy.get('h1').should('contain', 'Show #24251')
cy.get('p').should('contain', 'Animal Science')
cy.get('h1').should('contain', 'Show #24251')
cy.get('p').should('contain', 'Animal Science')
})
})
})

describe('dynamic catch-all SSR page', () => {
it('displays all URL parameters, including query string parameters', () => {
cy.visit('/shows/94/this-is-all/being/captured/yay?search=dog&custom-param=cat')
context('with catch-all route', () => {
it('displays all URL parameters, including query string parameters', () => {
cy.visit('/shows/94/this-is-all/being/captured/yay?search=dog&custom-param=cat')

// path parameters
cy.get('p').should('contain', '[0]: 94')
cy.get('p').should('contain', '[1]: this-is-all')
cy.get('p').should('contain', '[2]: being')
cy.get('p').should('contain', '[3]: captured')
cy.get('p').should('contain', '[4]: yay')
// path parameters
cy.get('p').should('contain', '[0]: 94')
cy.get('p').should('contain', '[1]: this-is-all')
cy.get('p').should('contain', '[2]: being')
cy.get('p').should('contain', '[3]: captured')
cy.get('p').should('contain', '[4]: yay')

// query string parameters
cy.get('p').should('contain', '[search]: dog')
cy.get('p').should('contain', '[custom-param]: cat')
// query string parameters
cy.get('p').should('contain', '[search]: dog')
cy.get('p').should('contain', '[custom-param]: cat')

cy.get('h1').should('contain', 'Show #94')
cy.get('p').should('contain', 'Defiance')
})
cy.get('h1').should('contain', 'Show #94')
cy.get('p').should('contain', 'Defiance')
})

it('displays all URL parameters when SSR-ing, including query string parameters', () => {
cy.visit('/shows/94/this-is-all/being/captured/yay?search=dog&custom-param=cat')
it('displays all URL parameters when SSR-ing, including query string parameters', () => {
cy.visit('/shows/94/this-is-all/being/captured/yay?search=dog&custom-param=cat')

// path parameters
cy.get('p').should('contain', '[0]: 94')
cy.get('p').should('contain', '[1]: this-is-all')
cy.get('p').should('contain', '[2]: being')
cy.get('p').should('contain', '[3]: captured')
cy.get('p').should('contain', '[4]: yay')
// path parameters
cy.get('p').should('contain', '[0]: 94')
cy.get('p').should('contain', '[1]: this-is-all')
cy.get('p').should('contain', '[2]: being')
cy.get('p').should('contain', '[3]: captured')
cy.get('p').should('contain', '[4]: yay')

// query string parameters
cy.get('p').should('contain', '[search]: dog')
cy.get('p').should('contain', '[custom-param]: cat')
// query string parameters
cy.get('p').should('contain', '[search]: dog')
cy.get('p').should('contain', '[custom-param]: cat')

cy.get('h1').should('contain', 'Show #94')
cy.get('p').should('contain', 'Defiance')
cy.get('h1').should('contain', 'Show #94')
cy.get('p').should('contain', 'Defiance')
})
})
})

describe('API endpoint', () => {
it('returns hello world, with all response headers', () => {
cy.request('/api/static').then(response => {
expect(response.headers['content-type']).to.include('application/json')
expect(response.headers['my-custom-header']).to.include('header123')
describe('getStaticProps', () => {
context('with static route', () => {
it('loads TV show', () => {
cy.visit('/getStaticProps/static')

expect(response.body).to.have.property('message', 'hello world :)')
cy.get('h1').should('contain', 'Show #71')
cy.get('p').should('contain', 'Dancing with the Stars')
})
})
})

describe('dynamic API endpoint', () => {
it('returns TV show', () => {
cy.request('/api/shows/305').then(response => {
expect(response.headers['content-type']).to.include('application/json')
it('loads page props from data .json file when navigating to it', () => {
cy.visit('/')
cy.window().then(w => w.noReload = true)

expect(response.body).to.have.property('show')
expect(response.body.show).to.have.property('id', 305)
expect(response.body.show).to.have.property('name', 'Black Mirror')
// Navigate to page and test that no reload is performed
// See: https://glebbahmutov.com/blog/detect-page-reload/
cy.contains('getStaticProps/static').click()
cy.window().should('have.property', 'noReload', true)

cy.get('h1').should('contain', 'Show #71')
cy.get('p').should('contain', 'Dancing with the Stars')
})
})
})

describe('catch-all API endpoint', () => {
it('returns all URL paremeters, including query string parameters', () => {
cy.request('/api/shows/590/this/path/is/captured?metric=dog&p2=cat')
.then(response => {
describe('API endpoint', () => {
context('with static route', () => {
it('returns hello world, with all response headers', () => {
cy.request('/api/static').then(response => {
expect(response.headers['content-type']).to.include('application/json')
expect(response.headers['my-custom-header']).to.include('header123')

// Params
expect(response.body).to.have.property('params')
expect(response.body.params).to.deep.eq([
'590', 'this', 'path', 'is', 'captured'
])
expect(response.body).to.have.property('message', 'hello world :)')
})
})
})

// Query string parameters
expect(response.body).to.have.property('queryStringParams')
expect(response.body.queryStringParams).to.deep.eq({
metric: 'dog',
p2: 'cat'
})
context('with dynamic route', () => {
it('returns TV show', () => {
cy.request('/api/shows/305').then(response => {
expect(response.headers['content-type']).to.include('application/json')

// Show
expect(response.body).to.have.property('show')
expect(response.body.show).to.have.property('id', 590)
expect(response.body.show).to.have.property('name', 'Pokémon')
expect(response.body.show).to.have.property('id', 305)
expect(response.body.show).to.have.property('name', 'Black Mirror')
})
})
})

context('with catch-all route', () => {
it('returns all URL paremeters, including query string parameters', () => {
cy.request('/api/shows/590/this/path/is/captured?metric=dog&p2=cat')
.then(response => {
expect(response.headers['content-type']).to.include('application/json')

// Params
expect(response.body).to.have.property('params')
expect(response.body.params).to.deep.eq([
'590', 'this', 'path', 'is', 'captured'
])

// Query string parameters
expect(response.body).to.have.property('queryStringParams')
expect(response.body.queryStringParams).to.deep.eq({
metric: 'dog',
p2: 'cat'
})

// Show
expect(response.body).to.have.property('show')
expect(response.body.show).to.have.property('id', 590)
expect(response.body.show).to.have.property('name', 'Pokémon')
})
})
})
})

describe('static page', () => {
it('renders', () => {
cy.visit('/static')
describe('pre-rendered HTML pages', () => {
context('with static route', () => {
it('renders', () => {
cy.visit('/static')

cy.get('p').should('contain', 'It is a static page.')
})
cy.get('p').should('contain', 'It is a static page.')
})

it('renders when SSR-ing', () => {
cy.visit('/static')
it('renders when SSR-ing', () => {
cy.visit('/static')

cy.get('p').should('contain', 'It is a static page.')
cy.get('p').should('contain', 'It is a static page.')
})
})
})

describe('dynamic static page', () => {
it('renders', () => {
cy.visit('/static/superdynamic')
context('with dynamic route', () => {
it('renders', () => {
cy.visit('/static/superdynamic')

cy.get('p').should('contain', 'It is a static page.')
cy.get('p').should('contain', 'it has a dynamic URL parameter: /static/:id.')
})
cy.get('p').should('contain', 'It is a static page.')
cy.get('p').should('contain', 'it has a dynamic URL parameter: /static/:id.')
})

it('renders when SSR-ing', () => {
cy.visit('/static/superdynamic')
it('renders when SSR-ing', () => {
cy.visit('/static/superdynamic')

cy.get('p').should('contain', 'It is a static page.')
cy.get('p').should('contain', 'it has a dynamic URL parameter: /static/:id.')
cy.get('p').should('contain', 'It is a static page.')
cy.get('p').should('contain', 'it has a dynamic URL parameter: /static/:id.')
})
})
})

Expand Down
Loading

0 comments on commit 89295e8

Please sign in to comment.