<ul dir="auto">
<li>[ x] I have searched the <a href="https://github.com/zeit/next.js/issues">issues</a> of this repository and believe that this is not a duplicate.</li>
</ul>
<h2 dir="auto">Expected Behavior</h2>


<p dir="auto">Clarify the section in the docs explaining the static folder convention and how it is handled by next. The docs should emphasize that static assets <em>must</em> be put in the static dir.</p>
<h2 dir="auto">Current Behavior</h2>


<p dir="auto">I only discovered that static assets <em>had</em> to come from the static dir after running into problems and then poring over many GH issues.</p>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have searched the <a href="https://github.com/zeit/next.js/issues">issues</a> of this repository and believe that this is not a duplicate.</li>
</ul>
<h2 dir="auto">Expected Behavior</h2>


<p dir="auto">Following the <code class="notranslate">custom-server-hapi</code> example with hapi's latest release should work.</p>
<h2 dir="auto">Current Behavior</h2>
<p dir="auto">I came across two issues when trying to implement a custom hapi 17 server.</p>
<ol dir="auto">
<li>The <code class="notranslate">server.connection</code> method was removed in favor of passing the connection props to the server's constructor I fixed it like this:</li>
</ol>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="
//BEFORE

app.prepare()
.then(() =&gt; {
  server.connection({ port })
  server.register(pluginOptions)
  .then(() =&gt; {
    server.route({
      method: 'GET',
      path: '/{p*}', /* catch all route */
      handler: defaultHandlerWrapper(app)
    })

    server.start().catch(error =&gt; {
      console.log('Error starting server')
      console.log(error)
    }).then(() =&gt; {
      console.log(`&gt; Ready on http://localhost:${port}`)
    })
  })
})

//AFTER

app.prepare().then(() =&gt; {
  const server = new Hapi.Server({ host, port }); 
  server.route({
    method: 'GET',
    path: '/{p*}' /* catch all route */,
    handler: defaultHandlerWrapper(app)
  }); 
  server.start(err =&gt; {
    if (err) throw err;
    console.log(`&gt; Ready on http://${host}:${port}`);
  }); 
});"><pre class="notranslate"><span class="pl-c">//BEFORE</span>

<span class="pl-s1">app</span><span class="pl-kos">.</span><span class="pl-en">prepare</span><span class="pl-kos">(</span><span class="pl-kos">)</span>
<span class="pl-kos">.</span><span class="pl-en">then</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-s1">server</span><span class="pl-kos">.</span><span class="pl-en">connection</span><span class="pl-kos">(</span><span class="pl-kos">{</span> port <span class="pl-kos">}</span><span class="pl-kos">)</span>
  <span class="pl-s1">server</span><span class="pl-kos">.</span><span class="pl-en">register</span><span class="pl-kos">(</span><span class="pl-s1">pluginOptions</span><span class="pl-kos">)</span>
  <span class="pl-kos">.</span><span class="pl-en">then</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-s1">server</span><span class="pl-kos">.</span><span class="pl-en">route</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
      <span class="pl-c1">method</span>: <span class="pl-s">'GET'</span><span class="pl-kos">,</span>
      <span class="pl-c1">path</span>: <span class="pl-s">'/{p*}'</span><span class="pl-kos">,</span> <span class="pl-c">/* catch all route */</span>
      <span class="pl-c1">handler</span>: <span class="pl-en">defaultHandlerWrapper</span><span class="pl-kos">(</span><span class="pl-s1">app</span><span class="pl-kos">)</span>
    <span class="pl-kos">}</span><span class="pl-kos">)</span>

    <span class="pl-s1">server</span><span class="pl-kos">.</span><span class="pl-en">start</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">catch</span><span class="pl-kos">(</span><span class="pl-s1">error</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
      <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">'Error starting server'</span><span class="pl-kos">)</span>
      <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s1">error</span><span class="pl-kos">)</span>
    <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">then</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
      <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">`&gt; Ready on http://localhost:<span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">port</span><span class="pl-kos">}</span></span>`</span><span class="pl-kos">)</span>
    <span class="pl-kos">}</span><span class="pl-kos">)</span>
  <span class="pl-kos">}</span><span class="pl-kos">)</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span>

<span class="pl-c">//AFTER</span>

<span class="pl-s1">app</span><span class="pl-kos">.</span><span class="pl-en">prepare</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">then</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-k">const</span> <span class="pl-s1">server</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">Hapi</span><span class="pl-kos">.</span><span class="pl-c1">Server</span><span class="pl-kos">(</span><span class="pl-kos">{</span> host<span class="pl-kos">,</span> port <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span> 
  <span class="pl-s1">server</span><span class="pl-kos">.</span><span class="pl-en">route</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
    <span class="pl-c1">method</span>: <span class="pl-s">'GET'</span><span class="pl-kos">,</span>
    <span class="pl-c1">path</span>: <span class="pl-s">'/{p*}'</span> <span class="pl-c">/* catch all route */</span><span class="pl-kos">,</span>
    <span class="pl-c1">handler</span>: <span class="pl-en">defaultHandlerWrapper</span><span class="pl-kos">(</span><span class="pl-s1">app</span><span class="pl-kos">)</span>
  <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span> 
  <span class="pl-s1">server</span><span class="pl-kos">.</span><span class="pl-en">start</span><span class="pl-kos">(</span><span class="pl-s1">err</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-s1">err</span><span class="pl-kos">)</span> <span class="pl-k">throw</span> <span class="pl-s1">err</span><span class="pl-kos">;</span>
    <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">`&gt; Ready on http://<span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">host</span><span class="pl-kos">}</span></span>:<span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">port</span><span class="pl-kos">}</span></span>`</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span> 
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<ol start="2" dir="auto">
<li>The defaultHandlerWrapper  was throwing this error <code class="notranslate">UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: x): Cannot set headers after they are sent to the client</code>. I fixed it like this:</li>
</ol>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="
//BEFORE

const defaultHandlerWrapper = app =&gt; {
  const handler = app.getRequestHandler()
  return ({ raw, url }, hapiReply) =&gt;
    handler(raw.req, raw.res, url)
      .then(() =&gt; {
        hapiReply.close(false)
      })
}

//AFTER

const { parse } = require('url');
const defaultHandlerWrapper = app =&gt; (
  { raw: { req, res }, url },
  hapiReply
) =&gt; {
  const parsedUrl = parse(url, true);
  const { pathname, query } = parsedUrl;
  return app.renderToHTML(req, res, pathname, query).then(hapiReply);
};"><pre class="notranslate"><span class="pl-c">//BEFORE</span>

<span class="pl-k">const</span> <span class="pl-en">defaultHandlerWrapper</span> <span class="pl-c1">=</span> <span class="pl-s1">app</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-k">const</span> <span class="pl-s1">handler</span> <span class="pl-c1">=</span> <span class="pl-s1">app</span><span class="pl-kos">.</span><span class="pl-en">getRequestHandler</span><span class="pl-kos">(</span><span class="pl-kos">)</span>
  <span class="pl-k">return</span> <span class="pl-kos">(</span><span class="pl-kos">{</span> raw<span class="pl-kos">,</span> url <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-s1">hapiReply</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span>
    <span class="pl-s1">handler</span><span class="pl-kos">(</span><span class="pl-s1">raw</span><span class="pl-kos">.</span><span class="pl-c1">req</span><span class="pl-kos">,</span> <span class="pl-s1">raw</span><span class="pl-kos">.</span><span class="pl-c1">res</span><span class="pl-kos">,</span> <span class="pl-s1">url</span><span class="pl-kos">)</span>
      <span class="pl-kos">.</span><span class="pl-en">then</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
        <span class="pl-s1">hapiReply</span><span class="pl-kos">.</span><span class="pl-en">close</span><span class="pl-kos">(</span><span class="pl-c1">false</span><span class="pl-kos">)</span>
      <span class="pl-kos">}</span><span class="pl-kos">)</span>
<span class="pl-kos">}</span>

<span class="pl-c">//AFTER</span>

<span class="pl-k">const</span> <span class="pl-kos">{</span> parse <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">'url'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">const</span> <span class="pl-en">defaultHandlerWrapper</span> <span class="pl-c1">=</span> <span class="pl-s1">app</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">(</span>
  <span class="pl-kos">{</span> <span class="pl-c1">raw</span>: <span class="pl-kos">{</span> req<span class="pl-kos">,</span> res <span class="pl-kos">}</span><span class="pl-kos">,</span> url <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-s1">hapiReply</span>
<span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-k">const</span> <span class="pl-s1">parsedUrl</span> <span class="pl-c1">=</span> <span class="pl-en">parse</span><span class="pl-kos">(</span><span class="pl-s1">url</span><span class="pl-kos">,</span> <span class="pl-c1">true</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-k">const</span> <span class="pl-kos">{</span> pathname<span class="pl-kos">,</span> query <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-s1">parsedUrl</span><span class="pl-kos">;</span>
  <span class="pl-k">return</span> <span class="pl-s1">app</span><span class="pl-kos">.</span><span class="pl-en">renderToHTML</span><span class="pl-kos">(</span><span class="pl-s1">req</span><span class="pl-kos">,</span> <span class="pl-s1">res</span><span class="pl-kos">,</span> <span class="pl-s1">pathname</span><span class="pl-kos">,</span> <span class="pl-s1">query</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">then</span><span class="pl-kos">(</span><span class="pl-s1">hapiReply</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
<h2 dir="auto">Context</h2>


<p dir="auto">While following the <code class="notranslate">custom-server-hapi</code> example using the latest release of Hapi, I came across the issues described above. I managed to have it working by applying the fixes I attached to this issue. If this all makes sense I'm hapi (pun intended) to send a PR.</p>
<h2 dir="auto">Your Environment</h2>

<table role="table">
<thead>
<tr>
<th>Tech</th>
<th>Version</th>
</tr>
</thead>
<tbody>
<tr>
<td>next</td>
<td>4.1.4</td>
</tr>
<tr>
<td>node</td>
<td>9.2.0</td>
</tr>
<tr>
<td>OS</td>
<td>Linux hal9000 4.13.12-1-ARCH 1 SMP PREEMPT Wed Nov 8 11:54:06 CET 2017 x86_64 GNU/Linux</td>
</tr>
<tr>
<td>hapi</td>
<td>17.0.2</td>
</tr>
</tbody>
</table>