mars / heroku-cra-node

⚛️ How to use create-react-app with a custom Node server on Heroku
MIT License
927 stars 226 forks source link

I can't get this to work with apple app site association. #24

Closed dilizarov closed 6 years ago

dilizarov commented 6 years ago

I migrated over my CRA app to this from the old buildpack.

This solved it for me before, https://github.com/mars/create-react-app-buildpack/issues/19, but with this new buildpack, I don't think static.json is used, right?

In index.js, I've tried...

app.get('/apple-app-site-association', function(request, response) {
  response.sendFile(path.resolve(__dirname, '../react-ui/build', 'apple-app-site-association'))
})

Doesn't seem to do anything.

dilizarov commented 6 years ago

Actually... it might work. Frankly, I'm unsure.

That said, I don't need static.json though, correct?

mars commented 6 years ago

Hi @dilizarov 🙇‍♂️😄

Running locally, what does the request/response look like when you curl the endpoint?

curl -v http://localhost:5000/apple-app-site-association

You could try adding a logger to verify the handler is running:

app.get('/apple-app-site-association', function(request, response) {
  console.log(`Sending apple-app-site-association`);
  response.sendFile(path.resolve(__dirname, '../react-ui/build', 'apple-app-site-association'))
})

Where did you add the handler? That code would need to come before the final catch-all * route that serves the React app in server/index.js.

mars commented 6 years ago

Also worth noting that there’s already a static file handler in place:

  app.use(express.static(path.resolve(__dirname, '../react-ui/build')));

Files in public/ will be copied there during build.

mars commented 6 years ago

That said, I don't need static.json though, correct?

Yes, correct.

static.json is the configuration file for the static site buildpack, which is installed by create-react-app-buildpack.

This heroku-cra-node app uses only the Node buildpack, which is auto-detected because package.json is present.

mars commented 6 years ago

Closing, since @dilizarov seems unsure about this issue, and serving static files is known to work.

levous commented 4 years ago

I realize this is closed but I thought for others who are struggling unnecessarily, I'd post a solution...

It's really quite simple. Since the file does not have an extension, it will likely not serve as the correct mime type if you use static sendFile. While Apple's validation passed, it did not work for me. That may have nothing to do with the file but ensuring all requirements are met is a useful troubleshooting step for this annoying configuration dance. Here you go...

Create a sub folder called assets in the server directory and save a text file called apple-app-site-association Above the catch all handler in server/index.js add a rule to serve your assets/apple-app-site-association contents at both the apple recommended locations and explicitly set the mime type to json. Be sure to import fs to read the file

// top of file ...
const fs = require('fs');

// below rule for  '../react-ui/build' ...

var appleAppSiteAssociationContents = fs.readFileSync(path.resolve(__dirname, './assets/apple-app-site-association'), 'utf8');

// Host apple-app-site-association file for Apple iOS Associated Domains https://developer.apple.com/library/archive/documentation/General/Conceptual/AppSearch/UniversalLinks.html#//apple_ref/doc/uid/TP40016308-CH12-SW1
  app.get(['/apple-app-site-association', '/.well-known/apple-app-site-association'], function (req, res) {
    res.set('Content-Type', 'application/json');
    res.send(appleAppSiteAssociationContents);
  });

Its probably wise to check for the file first using fs.existsSync(path.resolve(__dirname, './assets/apple-app-site-association')) and handle accordingly.

Note: this will work in production because the react ui is compiled to static files and served via the express server. In development, using proxy, it will not serve the registered content from a browser request. I've verified it works when deployed to Heroku