Skip to content

Commit a79357f

Browse files
jesseditsontimneutkens
authored andcommittedOct 5, 2017
Allow use of filenames in exportPathMap (vercel#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
1 parent 594b214 commit a79357f

File tree

6 files changed

+42
-5
lines changed

6 files changed

+42
-5
lines changed
 

‎lib/router/index.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,12 @@ export function _rewriteUrlForNextExport (url) {
101101
let [path, qs] = url.split('?')
102102
path = path.replace(/\/$/, '')
103103

104-
let newPath = `${path}/`
104+
let newPath = path
105+
// Append a trailing slash if this path does not have an extension
106+
if (!/\.[^/]+\/?$/.test(path)) {
107+
newPath = `${path}/`
108+
}
109+
105110
if (qs) {
106111
newPath = `${newPath}?${qs}`
107112
}

‎readme.md

+3
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,7 @@ module.exports = {
10641064
return {
10651065
'/': { page: '/' },
10661066
'/about': { page: '/about' },
1067+
'/readme.md': { page: '/readme' },
10671068
'/p/hello-nextjs': { page: '/post', query: { title: 'hello-nextjs' } },
10681069
'/p/learn-nextjs': { page: '/post', query: { title: 'learn-nextjs' } },
10691070
'/p/deploy-nextjs': { page: '/post', query: { title: 'deploy-nextjs' } }
@@ -1072,6 +1073,8 @@ module.exports = {
10721073
}
10731074
```
10741075

1076+
> 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.
1077+
10751078
In that, you specify what are the pages you need to export as static HTML.
10761079

10771080
Then simply run these commands:

‎server/export.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import del from 'del'
22
import cp from 'recursive-copy'
33
import mkdirp from 'mkdirp-then'
44
import walk from 'walk'
5-
import { resolve, join, dirname, sep } from 'path'
5+
import { extname, resolve, join, dirname, sep } from 'path'
66
import { existsSync, readFileSync, writeFileSync } from 'fs'
77
import getConfig from './config'
88
import { renderToHTML } from './render'
@@ -96,7 +96,14 @@ export default async function (dir, options, configuration) {
9696
const req = { url: path }
9797
const res = {}
9898

99-
const htmlFilename = path === '/' ? 'index.html' : `${path}${sep}index.html`
99+
let htmlFilename = `${path}${sep}index.html`
100+
if (extname(path) !== '') {
101+
// If the path has an extension, use that as the filename instead
102+
htmlFilename = path
103+
} else if (path === '/') {
104+
// If the path is the root, just use index.html
105+
htmlFilename = 'index.html'
106+
}
100107
const baseDir = join(outDir, dirname(htmlFilename))
101108
const htmlFilepath = join(outDir, htmlFilename)
102109

‎test/integration/static/next.config.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ module.exports = {
99
'/dynamic-imports': { page: '/dynamic-imports' },
1010
'/dynamic': { page: '/dynamic', query: { text: 'cool dynamic text' } },
1111
'/dynamic/one': { page: '/dynamic', query: { text: 'next export is nice' } },
12-
'/dynamic/two': { page: '/dynamic', query: { text: 'zeit is awesome' } }
12+
'/dynamic/two': { page: '/dynamic', query: { text: 'zeit is awesome' } },
13+
'/file-name.md': { page: '/dynamic', query: { text: 'this file has an extension' } }
1314
}
1415
}
1516
}

‎test/integration/static/pages/index.js

+6
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ export default () => (
4444
>
4545
<a id='with-hash'>With Hash</a>
4646
</Link>
47+
<Link
48+
href='/dynamic?text=this+file+has+an+extension'
49+
as='/file-name.md'
50+
>
51+
<a id='path-with-extension'>Path with extension</a>
52+
</Link>
4753
<Link href='/level1'>
4854
<a id='level1-home-page'>Level1 home page</a>
4955
</Link>

‎test/integration/static/test/ssr.js

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* global describe, it, expect */
22
import { renderViaHTTP } from 'next-test-utils'
3+
import cheerio from 'cheerio'
34

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

12+
it('should render links correctly', async () => {
13+
const html = await renderViaHTTP(context.port, '/')
14+
const $ = cheerio.load(html)
15+
const dynamicLink = $('#dynamic-1').prop('href')
16+
const filePathLink = $('#path-with-extension').prop('href')
17+
expect(dynamicLink).toEqual('/dynamic/one/')
18+
expect(filePathLink).toEqual('/file-name.md')
19+
})
20+
1121
it('should render a page with getInitialProps', async() => {
1222
const html = await renderViaHTTP(context.port, '/dynamic')
1323
expect(html).toMatch(/cool dynamic text/)
@@ -20,7 +30,12 @@ export default function (context) {
2030

2131
it('should render pages with dynamic imports', async() => {
2232
const html = await renderViaHTTP(context.port, '/dynamic-imports')
23-
expect(html).toMatch(/Welcome to dynamic imports./)
33+
expect(html).toMatch(/Welcome to dynamic imports/)
34+
})
35+
36+
it('should render paths with extensions', async() => {
37+
const html = await renderViaHTTP(context.port, '/file-name.md')
38+
expect(html).toMatch(/this file has an extension/)
2439
})
2540

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

0 commit comments

Comments
 (0)
Please sign in to comment.