Giter Club home page Giter Club logo

prep's Introduction

prep has been deprecated in favor of newer tools like Gatsby and Next.js

prep npm version

Pre-renders your web app into static HTML based on your specified routes enabling SEO for single page applications.

NOTE: prep is now based on Chromeless. We'll shortly release an updated version.

Features

  • πŸ”Ž Makes your single page app SEO friendly
  • πŸš€ Improves loading speed up to 400x
  • ✨ Incredibly flexible and easy to use
  • πŸ“¦ Works out-of-the-box with any framework (React, Angular, Backbone...). No code-changes needed.

Install

npm install -g prep

Usage

Just run prep in your terminal or add it to the scripts as part of your build step in your package.json. If you don't provide a target-dir the contents of the source-dir will be overwritten.

  Usage: prep [options] <source-dir> [target-dir]

  Options:

    -h, --help           output usage information
    -c, --config [path]  Config file (Default: prep.js)
    -p, --port [port]    Phantom server port (Default: 45678)

In order to configure the routes which you'd like to pre-render you need to specifiy them in a Javascript config file with the following schema. If you don't provide a config file, prep will just pre-render the / route.

const defaultConfig = {
  routes: ['/'],
  timeout: 1000,
  dimensions: {
    width: 1440,
    height: 900,
  },
  https: false,
  hostname: 'http://localhost',
  useragent: 'Prep',
  minify: false,
  concurrency: 4,
  additionalSitemapUrls: [],
}
  • routes specifies the list of routes that the renderer should pass. (Default: ['/'])
  • timeout is the timeout for how long the renderer should wait for network requests. (Default: 1000)
  • dimensions the page dimensions in pixels that the renderer should use to render the site. (Default: 1440 x 900)
  • https prep uses https if true otherwise http
  • hostname is used to show the correct urls in the generated sitemap that is stored in [target-dir]/sitemap.xml
  • useragent is set a navigator.userAgent
  • minify is a boolean or a html-minifier configuration object.
  • concurrency controls how many routes are pre-rendered in parallel. (Default: 4)
  • additionalSitemapUrls is a list of URLs to include as well to the generated sitemap.xml. (Default: [])

Example prep.js

There are three different ways to configure prep. Which one you pick depends on your use case.

1. Javascript Object

The probably easiest way is to export a simple Javascript object.

exports.default = {
  routes: [
    '/',
    '/world'
  ]
}

2. Synchronous Function

You can also return a function that returns the config for prep.

exports.default = () => {
  return {
    routes: [
      '/',
      '/world'
    ]
  }
}

3. Asynchronous Function (Promise)

Furthermore you can also return a Promise or use ES7 features such as async & await (Babel pre-compile step needed).

export default async () => {
  const routes = await getRoutesAsync()
  return { routes }
}

How it works

The concept behind prep is very simple. prep starts a temporary local webserver and opens your provided routes via PhantomJS. Each route will be exported as a static HTML file. The resulting folder structure is the same as the structure of your routes.

Known Issues

  • If you want to use Object.assign() in your code, please add a polyfill like phantomjs-polyfill-object-assign, because prep uses PhantomJS, which doesn't support Object.assign() yet.

Help & Community Slack Status

Join our Slack community if you run into issues or have questions. We love talking to you!

Prisma

prep's People

Contributors

brene avatar kuldar avatar renebrandel avatar schickling avatar squirly avatar timsuchanek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

prep's Issues

Prerender Detection

Hello! Is there any way for the app to tell whether it's being prerendered? I know that with react-snap you can check with navigator.userAgent === 'ReactSnap', so I'm wondering if there's an equivalent for this prerenderer. Thanks :)

Example missing serving of static files

I just discovered this project which looks quite promising to enable SSR with almost no configuration overhead in my React projects. So I went to look at the example, which runs fine and generates static files as promised, but then these files are apparently not used when running npm start. It would be nice to have a minimal example showcasing how these generated files are actually combined with the rest of the development and deployment experience.

Breaking change from 1.6.0 to 1.6.1

Hi, I just recently installing prep version 1.6.1 and it didn't work because of the following errors:

Retry 1 for route: /
Retry 1 for route: /portfolio
Retry 2 for route: /
Retry 2 for route: /portfolio
Retry 3 for route: /
Retry 3 for route: /portfolio
Retry 4 for route: /
Retry 4 for route: /portfolio
Retry 5 for route: /
Retry 5 for route: /portfolio
Retry 6 for route: /
Retry 6 for route: /portfolio
Retry 7 for route: /
Retry 7 for route: /portfolio
Retry 8 for route: /
Retry 8 for route: /portfolio
Retry 9 for route: /
Retry 9 for route: /portfolio
Retry 10 for route: /
Retry 10 for route: /portfolio
{ Error: Command failed: cp -rf "/Users/antony/Documents/Code/Web/antonybudianto-web/.prep-tmp"/* "/Users/antony/Documents/Code/Web/antonybudianto-web/build"/
cp: /Users/antony/Documents/Code/Web/antonybudianto-web/.prep-tmp/*: No such file or directory
 `cp -rf "/Users/antony/Documents/Code/Web/antonybudianto-web/.prep-tmp"/* "/Users/antony/Documents/Code/Web/antonybudianto-web/build"/` (exited with error code 1)
    at callback (/Users/antony/Documents/Code/Web/antonybudianto-web/node_modules/child-process-promise/lib/index.js:33:27)

my prep.js:

exports.default = {
  routes: [
    "/",
    "/portfolio"
  ],
  timeout: 5000
}

When I downgraded to version 1.6.0, it worked well.
Thanks for the work!

Possible convergence with React-snapshot

Hi there! I'm currently building React-snapshot as a drop in prerenderer for React apps out of create-react-app. I'm currently working on a more comprehensive API for async stuff (geelen/react-snapshot#30), and hitting the limits of JSDOM.

Stumbled across this project and thought it might be worth combining effortsβ€”if not public API then the crawling/snapshotting code. I think this could offer a huge benefit over server rendering most React apps. But it'd benefit from some combined attention!

Anyway, πŸ‘‹

Testing prep

Not an issue with Prep per-se, but I'd like to know how I could go about testing if I've set up Prep correctly for SEO?

Thanks for sharing this BTW! SSR is a hassle and sometimes you just want to your simple non-SSR app MVP to be discoverable on search engines

Discovered edge cases

This is a list of weird edge cases which seemed to have caused problems with prep:

  • using the ref callback syntax of React (Code)
  • using window.innerWidth for media queries

State of the project

Hi @lastmjs! We're currently rewriting prep to use a headless version of Chrome capable of running on serverless functions. Stay tuned!
-- #10 (comment)

Is this project maintained?

There is react-snap which is basically doing the same and it uses puppeteer. Do not pay attention to the name, it does not depend on React or create-react-app, but it uses create-react-app conventions. It can work with any Single Page Application to pre-render it to HTML.

Related peterbe/minimalcss#23

Use Electron instead of PhantomJS

Why is this project using PhantomJS? Electron is more up-to-date and is even coming with true headless mode soon. Seems like a better choice.

Context Issue

I generated my build with the context name = books and base

<base href="/books/"/>

below is my configuration

{
    routes: ['/location/bangalore'],
    timeout: 5000,
    dimensions: {
      width: 375,
      height: 812,
    },
    https: false,
    hostname: 'http://localhost/books',
    useragent: 'Prep',
    minify: true,
    concurrency: 4,
    additionalSitemapUrls: [],
  }

Then i run this command

// books contain the index.html 
prep ./books/ ./build  

It retries 10 times and i get the error

ChildProcessError: Command failed: cp -rf "/Users/b0219479/Documents/Acquisition/react-growth-safo-ui/.prep-tmp"/* "/Users/b0219479/Documents/Acquisition/react-growth-safo-ui/build"/

Prepjs uses cached assets when a service worker is installed on the rendered site

I recently upgraded prepjs on a create-react-app project. When statically rendering my routes, it uses the cached service worker index.html instead of the generated one. My prep.js looks roughly like:

//define routes here
exports.default = () => ({
  routes,
  timeout: 1000,
  dimensions: {
    width: 1440,
    height: 900,
  },
  https: true,
  hostname: 'https://myhostname.com',
  minify: true,
})

I've tried clearing my browser cache, but of course, multiple routes just causes the serviceworker to cache assets for the next run. I'm sure there's some sort of workaround. Any ideas?

prep.js: unexpected token export

I tried the react-webpack example as follows:

npm install
npm install -g prep
npm run build

But I got this:

prep.js:1
(function (exports, require, module, __filename, __dirname) { export default {
                                                              ^^^^^^
SyntaxError: Unexpected token export
    at Object.exports.runInThisContext (vm.js:76:16)

It looks like it should run through babel but isn't? What am I missing?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.