2020-05-19 10:54:32 +02:00
const path = require ( 'path' )
const fs = require ( 'fs' )
2021-04-30 13:09:07 +02:00
const {
getUrlFromPagesDirectory ,
normalizeURL ,
execOnce ,
} = require ( '../utils/url' )
const pagesDirWarning = execOnce ( ( pagesDirs ) => {
console . warn (
` Pages directory cannot be found at ${ pagesDirs . join ( ' or ' ) } . ` +
` If using a custom path, please configure with the no-html-link-for-pages rule in your eslint config file `
)
} )
2020-05-19 10:54:32 +02:00
module . exports = {
meta : {
docs : {
description : 'Prohibit full page refresh for nextjs pages' ,
category : 'HTML' ,
recommended : true ,
} ,
fixable : null , // or "code" or "whitespace"
schema : [ 'pagesDirectory' ] ,
} ,
create : function ( context ) {
2020-09-18 02:09:25 +02:00
const [ customPagesDirectory ] = context . options
const pagesDirs = customPagesDirectory
? [ customPagesDirectory ]
: [
path . join ( context . getCwd ( ) , 'pages' ) ,
path . join ( context . getCwd ( ) , 'src' , 'pages' ) ,
]
const pagesDir = pagesDirs . find ( ( dir ) => fs . existsSync ( dir ) )
if ( ! pagesDir ) {
2021-04-30 13:09:07 +02:00
pagesDirWarning ( pagesDirs )
return { }
2020-05-19 10:54:32 +02:00
}
const urls = getUrlFromPagesDirectory ( '/' , pagesDir )
return {
JSXOpeningElement ( node ) {
if ( node . name . name !== 'a' ) {
return
}
if ( node . attributes . length === 0 ) {
return
}
2020-05-22 01:42:20 +02:00
const href = node . attributes . find (
( attr ) => attr . type === 'JSXAttribute' && attr . name . name === 'href'
)
2020-05-19 10:54:32 +02:00
if ( ! href || href . value . type !== 'Literal' ) {
return
}
const hrefPath = normalizeURL ( href . value . value )
2020-05-22 01:42:20 +02:00
// Outgoing links are ignored
if ( /^(https?:\/\/|\/\/)/ . test ( hrefPath ) ) {
return
}
2020-05-19 10:54:32 +02:00
urls . forEach ( ( url ) => {
if ( url . test ( normalizeURL ( hrefPath ) ) ) {
context . report ( {
node ,
2021-04-30 13:09:07 +02:00
message : ` Do not use the HTML <a> tag to navigate to ${ hrefPath } . Use Link from 'next/link' instead. See: https://nextjs.org/docs/messages/no-html-link-for-pages. ` ,
2020-05-19 10:54:32 +02:00
} )
}
} )
} ,
}
} ,
}