Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Allow use of filenames in exportPathMap (#2973)
* allow use of filenames in exportPathMap

* add link test and handling for file paths when flattening links for export

* add note about exporting file paths to readme.md
  • Loading branch information
jesseditson authored and timneutkens committed Oct 5, 2017
1 parent 594b214 commit a79357f
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 5 deletions.
7 changes: 6 additions & 1 deletion lib/router/index.js
Expand Up @@ -101,7 +101,12 @@ export function _rewriteUrlForNextExport (url) {
let [path, qs] = url.split('?')
path = path.replace(/\/$/, '')

let newPath = `${path}/`
let newPath = path
// Append a trailing slash if this path does not have an extension
if (!/\.[^/]+\/?$/.test(path)) {
newPath = `${path}/`
}

if (qs) {
newPath = `${newPath}?${qs}`
}
Expand Down
3 changes: 3 additions & 0 deletions readme.md
Expand Up @@ -1064,6 +1064,7 @@ module.exports = {
return {
'/': { page: '/' },
'/about': { page: '/about' },
'/readme.md': { page: '/readme' },
'/p/hello-nextjs': { page: '/post', query: { title: 'hello-nextjs' } },
'/p/learn-nextjs': { page: '/post', query: { title: 'learn-nextjs' } },
'/p/deploy-nextjs': { page: '/post', query: { title: 'deploy-nextjs' } }
Expand All @@ -1072,6 +1073,8 @@ module.exports = {
}
```

> Note that if the path ends with a directory, it will be exported as `/dir-name/index.html`, but if it ends with an extension, it will be exported as the specified filename, e.g. `/readme.md` above. If you use a file extension other than `.html`, you may need to set the `Content-Type` header to `text/html` when serving this content.
In that, you specify what are the pages you need to export as static HTML.

Then simply run these commands:
Expand Down
11 changes: 9 additions & 2 deletions server/export.js
Expand Up @@ -2,7 +2,7 @@ import del from 'del'
import cp from 'recursive-copy'
import mkdirp from 'mkdirp-then'
import walk from 'walk'
import { resolve, join, dirname, sep } from 'path'
import { extname, resolve, join, dirname, sep } from 'path'
import { existsSync, readFileSync, writeFileSync } from 'fs'
import getConfig from './config'
import { renderToHTML } from './render'
Expand Down Expand Up @@ -96,7 +96,14 @@ export default async function (dir, options, configuration) {
const req = { url: path }
const res = {}

const htmlFilename = path === '/' ? 'index.html' : `${path}${sep}index.html`
let htmlFilename = `${path}${sep}index.html`
if (extname(path) !== '') {
// If the path has an extension, use that as the filename instead
htmlFilename = path
} else if (path === '/') {
// If the path is the root, just use index.html
htmlFilename = 'index.html'
}
const baseDir = join(outDir, dirname(htmlFilename))
const htmlFilepath = join(outDir, htmlFilename)

Expand Down
3 changes: 2 additions & 1 deletion test/integration/static/next.config.js
Expand Up @@ -9,7 +9,8 @@ module.exports = {
'/dynamic-imports': { page: '/dynamic-imports' },
'/dynamic': { page: '/dynamic', query: { text: 'cool dynamic text' } },
'/dynamic/one': { page: '/dynamic', query: { text: 'next export is nice' } },
'/dynamic/two': { page: '/dynamic', query: { text: 'zeit is awesome' } }
'/dynamic/two': { page: '/dynamic', query: { text: 'zeit is awesome' } },
'/file-name.md': { page: '/dynamic', query: { text: 'this file has an extension' } }
}
}
}
6 changes: 6 additions & 0 deletions test/integration/static/pages/index.js
Expand Up @@ -44,6 +44,12 @@ export default () => (
>
<a id='with-hash'>With Hash</a>
</Link>
<Link
href='/dynamic?text=this+file+has+an+extension'
as='/file-name.md'
>
<a id='path-with-extension'>Path with extension</a>
</Link>
<Link href='/level1'>
<a id='level1-home-page'>Level1 home page</a>
</Link>
Expand Down
17 changes: 16 additions & 1 deletion test/integration/static/test/ssr.js
@@ -1,5 +1,6 @@
/* global describe, it, expect */
import { renderViaHTTP } from 'next-test-utils'
import cheerio from 'cheerio'

export default function (context) {
describe('Render via SSR', () => {
Expand All @@ -8,6 +9,15 @@ export default function (context) {
expect(html).toMatch(/This is the home page/)
})

it('should render links correctly', async () => {
const html = await renderViaHTTP(context.port, '/')
const $ = cheerio.load(html)
const dynamicLink = $('#dynamic-1').prop('href')
const filePathLink = $('#path-with-extension').prop('href')
expect(dynamicLink).toEqual('/dynamic/one/')
expect(filePathLink).toEqual('/file-name.md')
})

it('should render a page with getInitialProps', async() => {
const html = await renderViaHTTP(context.port, '/dynamic')
expect(html).toMatch(/cool dynamic text/)
Expand All @@ -20,7 +30,12 @@ export default function (context) {

it('should render pages with dynamic imports', async() => {
const html = await renderViaHTTP(context.port, '/dynamic-imports')
expect(html).toMatch(/Welcome to dynamic imports./)
expect(html).toMatch(/Welcome to dynamic imports/)
})

it('should render paths with extensions', async() => {
const html = await renderViaHTTP(context.port, '/file-name.md')
expect(html).toMatch(/this file has an extension/)
})

it('should give empty object for query if there is no query', async() => {
Expand Down

0 comments on commit a79357f

Please sign in to comment.