4

In the express, we can just use following codes to deal with the request. The server side will send index.html when the request that isn't handled by router.

app.get('*', function (request, response){
  response.sendFile(path.resolve(__dirname, '../public', 'index.html'))
})

But in koa, the following code don't work. When the request isn't handled by koa-router, it will return 404 instead of index.html.

var send = require('koa-send')
var serve = require('koa-static')
var router = require('koa-router')
var koa = require('koa')
var app = koa();

app.use(serve(__dirname+'/../public'));
app.use(function *(){
   yield send(this, path.join(__dirname, '/../public/','index.html' )); })
app.use(router.routes())

following code also don't work

router
  .get('*', function* () {
    yield send(this, __dirname +'/../public/index.html')
  })
Mia
  • 107
  • 6
  • 2
    Could you define *"don't work"*? Does it throw errors? Does it do nothing? Does it return pictures of Rick Astley? – ivarni Aug 09 '16 at 13:32
  • @ivarni Sorry for the absence of the clear information. I have updated the question just now. – Mia Aug 10 '16 at 07:14

2 Answers2

0
router.get('*', async function(ctx, next) {
  var html = fs.readFileSync(path.resolve('./build/index.html'));
  ctx.type = 'html';
  ctx.body = html;
})

this works for me

Mia
  • 107
  • 6
-1

Essentially what you're trying to achieve is server-rendering. You need to write route configuration with match & RouterContext. react-router has detailed documentation for this.

Server Rendering in react-router

In case of koa, it can roughly be done in this way.

import router from 'koa-router'
import { match, RouterContext } from 'react-router'

const koaRouter = router()

const otherRouter = () => {
   return new Promise((resolve, reject) => {
    match({ routes, location }, (error, redirectLocation, renderProps) => { 
   ...
   ..
   .
 }
}

koaRouter
    .use(otherRouter)

I found couple of repos online which seem pretty decent. I haven't verified them though.

breko-hub

koa-react-isomoprhic

Deadfish
  • 2,047
  • 16
  • 17
  • 1
    It sounds more like what they're trying to achieve is using the HTML5 history API, which in no way requires you to render serverside. But for that to work with page refresh every URL needs to return the same `index.html` file. The working `express` example is a clear indication of that. – ivarni Aug 09 '16 at 18:58