├── .eslintignore ├── .eslintrc.js ├── .nvmrc ├── .prettierrc ├── .travis.yml ├── README.md ├── examples ├── e-commerce │ ├── .babelrc │ ├── .editorconfig │ ├── .gitignore │ ├── .postcssrc.js │ ├── README.md │ ├── build │ │ ├── build.js │ │ ├── check-versions.js │ │ ├── dev-client.js │ │ ├── dev-server.js │ │ ├── utils.js │ │ ├── vue-loader.conf.js │ │ ├── webpack.base.conf.js │ │ ├── webpack.dev.conf.js │ │ └── webpack.prod.conf.js │ ├── config │ │ ├── dev.env.js │ │ ├── index.js │ │ └── prod.env.js │ ├── index.html │ ├── package.json │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ └── logo.png │ │ └── main.js │ └── static │ │ └── .gitkeep ├── multi-index │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── index.html │ ├── package.json │ ├── src │ │ ├── App.vue │ │ └── main.js │ └── webpack.config.js ├── nuxt │ ├── .gitignore │ ├── README.md │ ├── nuxt.config.js │ ├── package.json │ ├── pages │ │ ├── index.vue │ │ └── search.vue │ └── plugins │ │ └── vue-instantsearch.js ├── quick-start │ ├── .gitignore │ ├── index.html │ ├── package.json │ └── styles.css ├── ssr │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── build │ │ ├── webpack.base.config.js │ │ ├── webpack.client.config.js │ │ └── webpack.server.config.js │ ├── package.json │ ├── server.js │ └── src │ │ ├── App.vue │ │ ├── Search.vue │ │ ├── assets │ │ └── logo.png │ │ ├── index.template.html │ │ ├── main.client.js │ │ ├── main.js │ │ ├── main.server.js │ │ └── router.js └── vue-router │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── index.html │ ├── package.json │ ├── src │ ├── App.vue │ ├── Search.vue │ └── main.js │ └── webpack.config.js ├── package.json ├── renovate.json ├── scripts └── build.sh └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .nuxt 3 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['algolia/vue'], 3 | }; 4 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 9.11.2 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "es5" 4 | } 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | cache: 3 | yarn: true 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vue InstantSearch examples 2 | 3 | Some examples for [Vue InstantSearch](https://community.algolia.com/vue-instantsearch) by Algolia. 4 | 5 | To start, you need to run `yarn` to install all of the dependencies, then go to a subdirectory, and run the script you want, like `yarn start`. 6 | 7 | ## Included examples 8 | 9 | * e-commerce 10 | * multi-index 11 | * nuxt 12 | * quick-start 13 | * ssr 14 | * vue-router 15 | -------------------------------------------------------------------------------- /examples/e-commerce/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { "modules": false }], 4 | "stage-2" 5 | ], 6 | "plugins": ["transform-runtime"], 7 | "comments": false, 8 | "env": { 9 | "test": { 10 | "presets": ["env", "stage-2"], 11 | "plugins": [ "istanbul" ] 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /examples/e-commerce/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /examples/e-commerce/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log 5 | yarn-error.log 6 | -------------------------------------------------------------------------------- /examples/e-commerce/.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | // to edit target browsers: use "browserlist" field in package.json 6 | "autoprefixer": {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/e-commerce/README.md: -------------------------------------------------------------------------------- 1 | # e-commerce example 2 | 3 | > Algolia + Vue.js in an e-commerce site 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | 17 | # build for production and view the bundle analyzer report 18 | npm run build --report 19 | ``` 20 | 21 | For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 22 | -------------------------------------------------------------------------------- /examples/e-commerce/build/build.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-commonjs, no-console */ 2 | require('./check-versions')(); 3 | 4 | process.env.NODE_ENV = 'production'; 5 | 6 | const ora = require('ora'); 7 | const rm = require('rimraf'); 8 | const path = require('path'); 9 | const chalk = require('chalk'); 10 | const webpack = require('webpack'); 11 | const config = require('../config'); 12 | const webpackConfig = require('./webpack.prod.conf'); 13 | 14 | const spinner = ora('building for production...'); 15 | spinner.start(); 16 | 17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 18 | if (err) throw err; 19 | webpack(webpackConfig, (_err, stats) => { 20 | spinner.stop(); 21 | if (_err) throw _err; 22 | process.stdout.write( 23 | `${stats.toString({ 24 | colors: true, 25 | modules: false, 26 | children: false, 27 | chunks: false, 28 | chunkModules: false, 29 | })}\n\n` 30 | ); 31 | 32 | console.log(chalk.cyan(' Build complete.\n')); 33 | console.log( 34 | chalk.yellow( 35 | ' Tip: built files are meant to be served over an HTTP server.\n' + 36 | " Opening index.html over file:// won't work.\n" 37 | ) 38 | ); 39 | }); 40 | }); 41 | -------------------------------------------------------------------------------- /examples/e-commerce/build/check-versions.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-commonjs, no-process-exit, no-console */ 2 | 3 | const chalk = require('chalk'); 4 | const semver = require('semver'); 5 | const packageConfig = require('../package.json'); 6 | 7 | function exec(cmd) { 8 | return require('child_process') 9 | .execSync(cmd) 10 | .toString() 11 | .trim(); 12 | } 13 | 14 | const versionRequirements = [ 15 | { 16 | name: 'node', 17 | currentVersion: semver.clean(process.version), 18 | versionRequirement: packageConfig.engines.node, 19 | }, 20 | { 21 | name: 'npm', 22 | currentVersion: exec('npm --version'), 23 | versionRequirement: packageConfig.engines.npm, 24 | }, 25 | ]; 26 | 27 | module.exports = function() { 28 | const warnings = []; 29 | for (let i = 0; i < versionRequirements.length; i++) { 30 | const mod = versionRequirements[i]; 31 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 32 | warnings.push( 33 | `${mod.name}: ${chalk.red(mod.currentVersion)} should be ${chalk.green( 34 | mod.versionRequirement 35 | )}` 36 | ); 37 | } 38 | } 39 | 40 | if (warnings.length) { 41 | console.log(''); 42 | console.log( 43 | chalk.yellow( 44 | 'To use this template, you must update following to modules:' 45 | ) 46 | ); 47 | console.log(); 48 | for (let i = 0; i < warnings.length; i++) { 49 | const warning = warnings[i]; 50 | console.log(` ${warning}`); 51 | } 52 | console.log(); 53 | process.exit(1); 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /examples/e-commerce/build/dev-client.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-commonjs */ 2 | 3 | require('eventsource-polyfill'); 4 | const hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true'); 5 | 6 | hotClient.subscribe(event => { 7 | if (event.action === 'reload') { 8 | window.location.reload(); 9 | } 10 | }); 11 | -------------------------------------------------------------------------------- /examples/e-commerce/build/dev-server.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-commonjs, no-console */ 2 | 3 | require('./check-versions')(); 4 | 5 | const config = require('../config'); 6 | if (!process.env.NODE_ENV) { 7 | process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV); 8 | } 9 | 10 | const opn = require('opn'); 11 | const path = require('path'); 12 | const express = require('express'); 13 | const webpack = require('webpack'); 14 | const proxyMiddleware = require('http-proxy-middleware'); 15 | const webpackConfig = require('./webpack.dev.conf'); 16 | 17 | // default port where dev server listens for incoming traffic 18 | const port = process.env.PORT || config.dev.port; 19 | // automatically open browser, if not set will be false 20 | const autoOpenBrowser = Boolean(config.dev.autoOpenBrowser); 21 | // Define HTTP proxies to your custom API backend 22 | // https://github.com/chimurai/http-proxy-middleware 23 | const proxyTable = config.dev.proxyTable; 24 | 25 | const app = express(); 26 | const compiler = webpack(webpackConfig); 27 | 28 | const devMiddleware = require('webpack-dev-middleware')(compiler, { 29 | publicPath: webpackConfig.output.publicPath, 30 | quiet: true, 31 | }); 32 | 33 | const hotMiddleware = require('webpack-hot-middleware')(compiler, { 34 | log: () => {}, 35 | }); 36 | // force page reload when html-webpack-plugin template changes 37 | compiler.plugin('compilation', compilation => { 38 | compilation.plugin('html-webpack-plugin-after-emit', (data, cb) => { 39 | hotMiddleware.publish({ action: 'reload' }); 40 | cb(); 41 | }); 42 | }); 43 | 44 | // proxy api requests 45 | Object.keys(proxyTable).forEach(context => { 46 | let options = proxyTable[context]; 47 | if (typeof options === 'string') { 48 | options = { target: options }; 49 | } 50 | app.use(proxyMiddleware(options.filter || context, options)); 51 | }); 52 | 53 | // handle fallback for HTML5 history API 54 | app.use(require('connect-history-api-fallback')()); 55 | 56 | // serve webpack bundle output 57 | app.use(devMiddleware); 58 | 59 | // enable hot-reload and state-preserving 60 | // compilation error display 61 | app.use(hotMiddleware); 62 | 63 | // serve pure static assets 64 | const staticPath = path.posix.join( 65 | config.dev.assetsPublicPath, 66 | config.dev.assetsSubDirectory 67 | ); 68 | app.use(staticPath, express.static('./static')); 69 | 70 | const uri = `http://localhost:${port}`; 71 | 72 | devMiddleware.waitUntilValid(() => { 73 | console.log(`> Listening at ${uri}\n`); 74 | }); 75 | 76 | module.exports = app.listen(port, err => { 77 | if (err) { 78 | console.log(err); 79 | return; 80 | } 81 | 82 | // when env is testing, don't need open it 83 | if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') { 84 | opn(uri); 85 | } 86 | }); 87 | -------------------------------------------------------------------------------- /examples/e-commerce/build/utils.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-commonjs */ 2 | 3 | const path = require('path'); 4 | const config = require('../config'); 5 | const ExtractTextPlugin = require('extract-text-webpack-plugin'); 6 | 7 | exports.assetsPath = function(_path) { 8 | const assetsSubDirectory = 9 | process.env.NODE_ENV === 'production' 10 | ? config.build.assetsSubDirectory 11 | : config.dev.assetsSubDirectory; 12 | return path.posix.join(assetsSubDirectory, _path); 13 | }; 14 | 15 | exports.cssLoaders = function(options = {}) { 16 | const cssLoader = { 17 | loader: 'css-loader', 18 | options: { 19 | minimize: process.env.NODE_ENV === 'production', 20 | sourceMap: options.sourceMap, 21 | }, 22 | }; 23 | 24 | // generate loader string to be used with extract text plugin 25 | function generateLoaders(loader, loaderOptions) { 26 | const loaders = [cssLoader]; 27 | if (loader) { 28 | loaders.push({ 29 | loader: `${loader}-loader`, 30 | options: Object.assign({}, loaderOptions, { 31 | sourceMap: options.sourceMap, 32 | }), 33 | }); 34 | } 35 | 36 | // Extract CSS when that option is specified 37 | // (which is the case during production build) 38 | if (options.extract) { 39 | return ExtractTextPlugin.extract({ 40 | use: loaders, 41 | fallback: 'vue-style-loader', 42 | }); 43 | } else { 44 | return ['vue-style-loader'].concat(loaders); 45 | } 46 | } 47 | 48 | // http://vuejs.github.io/vue-loader/en/configurations/extract-css.html 49 | return { 50 | css: generateLoaders(), 51 | postcss: generateLoaders(), 52 | less: generateLoaders('less'), 53 | sass: generateLoaders('sass', { indentedSyntax: true }), 54 | scss: generateLoaders('sass'), 55 | stylus: generateLoaders('stylus'), 56 | styl: generateLoaders('stylus'), 57 | }; 58 | }; 59 | 60 | // Generate loaders for standalone style files (outside of .vue) 61 | exports.styleLoaders = function(options) { 62 | const output = []; 63 | const loaders = exports.cssLoaders(options); 64 | for (const extension in loaders) { 65 | if (loaders.hasOwnProperty(extension)) { 66 | const loader = loaders[extension]; 67 | output.push({ 68 | test: new RegExp(`\\.${extension}$`), 69 | use: loader, 70 | }); 71 | } 72 | } 73 | return output; 74 | }; 75 | -------------------------------------------------------------------------------- /examples/e-commerce/build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-commonjs */ 2 | 3 | const utils = require('./utils'); 4 | const config = require('../config'); 5 | const isProduction = process.env.NODE_ENV === 'production'; 6 | 7 | module.exports = { 8 | loaders: utils.cssLoaders({ 9 | sourceMap: isProduction 10 | ? config.build.productionSourceMap 11 | : config.dev.cssSourceMap, 12 | extract: isProduction, 13 | }), 14 | }; 15 | -------------------------------------------------------------------------------- /examples/e-commerce/build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-commonjs */ 2 | 3 | const path = require('path'); 4 | const utils = require('./utils'); 5 | const config = require('../config'); 6 | const vueLoaderConfig = require('./vue-loader.conf'); 7 | 8 | function resolve(dir) { 9 | return path.join(__dirname, '..', dir); 10 | } 11 | 12 | module.exports = { 13 | entry: { 14 | app: './src/main.js', 15 | }, 16 | output: { 17 | path: config.build.assetsRoot, 18 | filename: '[name].js', 19 | publicPath: 20 | process.env.NODE_ENV === 'production' 21 | ? config.build.assetsPublicPath 22 | : config.dev.assetsPublicPath, 23 | }, 24 | resolve: { 25 | extensions: ['.js', '.vue', '.json'], 26 | alias: { 27 | vue$: 'vue/dist/vue.esm.js', 28 | '@': resolve('src'), 29 | }, 30 | }, 31 | module: { 32 | rules: [ 33 | { 34 | test: /\.vue$/, 35 | loader: 'vue-loader', 36 | options: vueLoaderConfig, 37 | }, 38 | { 39 | test: /\.js$/, 40 | loader: 'babel-loader', 41 | include: [resolve('src'), resolve('test')], 42 | }, 43 | { 44 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 45 | loader: 'url-loader', 46 | query: { 47 | limit: 10000, 48 | name: utils.assetsPath('img/[name].[hash:7].[ext]'), 49 | }, 50 | }, 51 | { 52 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 53 | loader: 'url-loader', 54 | query: { 55 | limit: 10000, 56 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]'), 57 | }, 58 | }, 59 | ], 60 | }, 61 | }; 62 | -------------------------------------------------------------------------------- /examples/e-commerce/build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-commonjs */ 2 | 3 | const utils = require('./utils'); 4 | const webpack = require('webpack'); 5 | const config = require('../config'); 6 | const merge = require('webpack-merge'); 7 | const baseWebpackConfig = require('./webpack.base.conf'); 8 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 9 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin'); 10 | 11 | // add hot-reload related code to entry chunks 12 | Object.keys(baseWebpackConfig.entry).forEach(name => { 13 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat( 14 | baseWebpackConfig.entry[name] 15 | ); 16 | }); 17 | 18 | module.exports = merge(baseWebpackConfig, { 19 | module: { 20 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap }), 21 | }, 22 | // cheap-module-eval-source-map is faster for development 23 | devtool: '#cheap-module-eval-source-map', 24 | plugins: [ 25 | new webpack.DefinePlugin({ 26 | 'process.env': config.dev.env, 27 | }), 28 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage 29 | new webpack.HotModuleReplacementPlugin(), 30 | new webpack.NoEmitOnErrorsPlugin(), 31 | // https://github.com/ampedandwired/html-webpack-plugin 32 | new HtmlWebpackPlugin({ 33 | filename: 'index.html', 34 | template: 'index.html', 35 | inject: true, 36 | }), 37 | new FriendlyErrorsPlugin(), 38 | ], 39 | }); 40 | -------------------------------------------------------------------------------- /examples/e-commerce/build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-commonjs */ 2 | 3 | const path = require('path'); 4 | const utils = require('./utils'); 5 | const webpack = require('webpack'); 6 | const config = require('../config'); 7 | const merge = require('webpack-merge'); 8 | const baseWebpackConfig = require('./webpack.base.conf'); 9 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 10 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 11 | const ExtractTextPlugin = require('extract-text-webpack-plugin'); 12 | const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin'); 13 | 14 | const env = config.build.env; 15 | 16 | const webpackConfig = merge(baseWebpackConfig, { 17 | module: { 18 | rules: utils.styleLoaders({ 19 | sourceMap: config.build.productionSourceMap, 20 | extract: true, 21 | }), 22 | }, 23 | devtool: config.build.productionSourceMap ? '#source-map' : false, 24 | output: { 25 | path: config.build.assetsRoot, 26 | filename: utils.assetsPath('js/[name].[chunkhash].js'), 27 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js'), 28 | }, 29 | plugins: [ 30 | // http://vuejs.github.io/vue-loader/en/workflow/production.html 31 | new webpack.DefinePlugin({ 32 | 'process.env': env, 33 | }), 34 | new webpack.optimize.UglifyJsPlugin({ 35 | compress: { 36 | warnings: false, 37 | }, 38 | sourceMap: true, 39 | }), 40 | // extract css into its own file 41 | new ExtractTextPlugin({ 42 | filename: utils.assetsPath('css/[name].[contenthash].css'), 43 | }), 44 | // Compress extracted CSS. We are using this plugin so that possible 45 | // duplicated CSS from different components can be deduped. 46 | new OptimizeCSSPlugin(), 47 | // generate dist index.html with correct asset hash for caching. 48 | // you can customize output by editing /index.html 49 | // see https://github.com/ampedandwired/html-webpack-plugin 50 | new HtmlWebpackPlugin({ 51 | filename: config.build.index, 52 | template: 'index.html', 53 | inject: true, 54 | minify: { 55 | removeComments: true, 56 | collapseWhitespace: true, 57 | removeAttributeQuotes: true, 58 | // more options: 59 | // https://github.com/kangax/html-minifier#options-quick-reference 60 | }, 61 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin 62 | chunksSortMode: 'dependency', 63 | }), 64 | // split vendor js into its own file 65 | new webpack.optimize.CommonsChunkPlugin({ 66 | name: 'vendor', 67 | minChunks(module) { 68 | // any required modules inside node_modules are extracted to vendor 69 | return ( 70 | module.resource && 71 | /\.js$/.test(module.resource) && 72 | module.resource.indexOf(path.join(__dirname, '../node_modules')) === 0 73 | ); 74 | }, 75 | }), 76 | // extract webpack runtime and module manifest to its own file in order to 77 | // prevent vendor hash from being updated whenever app bundle is updated 78 | new webpack.optimize.CommonsChunkPlugin({ 79 | name: 'manifest', 80 | chunks: ['vendor'], 81 | }), 82 | // copy custom static assets 83 | new CopyWebpackPlugin([ 84 | { 85 | from: path.resolve(__dirname, '../static'), 86 | to: config.build.assetsSubDirectory, 87 | ignore: ['.*'], 88 | }, 89 | ]), 90 | ], 91 | }); 92 | 93 | if (config.build.productionGzip) { 94 | // eslint-disable-next-line import/no-extraneous-dependencies 95 | const CompressionWebpackPlugin = require('compression-webpack-plugin'); 96 | 97 | webpackConfig.plugins.push( 98 | new CompressionWebpackPlugin({ 99 | asset: '[path].gz[query]', 100 | algorithm: 'gzip', 101 | test: new RegExp( 102 | `\\.(${config.build.productionGzipExtensions.join('|')})$` 103 | ), 104 | threshold: 10240, 105 | minRatio: 0.8, 106 | }) 107 | ); 108 | } 109 | 110 | if (config.build.bundleAnalyzerReport) { 111 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer') 112 | .BundleAnalyzerPlugin; 113 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()); 114 | } 115 | 116 | module.exports = webpackConfig; 117 | -------------------------------------------------------------------------------- /examples/e-commerce/config/dev.env.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-commonjs */ 2 | 3 | const merge = require('webpack-merge'); 4 | const prodEnv = require('./prod.env'); 5 | 6 | module.exports = merge(prodEnv, { 7 | NODE_ENV: '"development"', 8 | }); 9 | -------------------------------------------------------------------------------- /examples/e-commerce/config/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-commonjs */ 2 | 3 | // see http://vuejs-templates.github.io/webpack for documentation. 4 | const path = require('path'); 5 | 6 | module.exports = { 7 | build: { 8 | env: require('./prod.env'), 9 | index: path.resolve(__dirname, '../dist/index.html'), 10 | assetsRoot: path.resolve(__dirname, '../dist'), 11 | assetsSubDirectory: 'static', 12 | assetsPublicPath: '/', 13 | productionSourceMap: true, 14 | // Gzip off by default as many popular static hosts such as 15 | // Surge or Netlify already gzip all static assets for you. 16 | // Before setting to `true`, make sure to: 17 | // npm install --save-dev compression-webpack-plugin 18 | productionGzip: false, 19 | productionGzipExtensions: ['js', 'css'], 20 | // Run the build command with an extra argument to 21 | // View the bundle analyzer report after build finishes: 22 | // `npm run build --report` 23 | // Set to `true` or `false` to always turn it on or off 24 | bundleAnalyzerReport: process.env.npm_config_report, 25 | }, 26 | dev: { 27 | env: require('./dev.env'), 28 | port: 8080, 29 | autoOpenBrowser: true, 30 | assetsSubDirectory: 'static', 31 | assetsPublicPath: '/', 32 | proxyTable: {}, 33 | // CSS Sourcemaps off by default because relative paths are "buggy" 34 | // with this option, according to the CSS-Loader README 35 | // (https://github.com/webpack/css-loader#sourcemaps) 36 | // In our experience, they generally work as expected, 37 | // just be aware of this issue when enabling this option. 38 | cssSourceMap: false, 39 | }, 40 | }; 41 | -------------------------------------------------------------------------------- /examples/e-commerce/config/prod.env.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-commonjs */ 2 | module.exports = { 3 | NODE_ENV: '"production"', 4 | }; 5 | -------------------------------------------------------------------------------- /examples/e-commerce/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vue.js & Algolia - Example store 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /examples/e-commerce/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "example-e-commerce", 4 | "version": "1.0.0", 5 | "description": "Algolia + Vue.js playground", 6 | "author": "Raymond Rutjes ", 7 | "scripts": { 8 | "dev": "node build/dev-server.js", 9 | "build": "node build/build.js" 10 | }, 11 | "dependencies": { 12 | "vue": "^2.4.2", 13 | "vue-instantsearch": "^1.4.0" 14 | }, 15 | "devDependencies": { 16 | "autoprefixer": "^7.2.5", 17 | "babel-core": "^6.22.1", 18 | "babel-loader": "^7.1.2", 19 | "babel-plugin-transform-runtime": "^6.22.0", 20 | "babel-preset-env": "^1.2.1", 21 | "babel-preset-stage-2": "^6.22.0", 22 | "babel-register": "^6.22.0", 23 | "chalk": "^2.3.0", 24 | "connect-history-api-fallback": "^1.3.0", 25 | "copy-webpack-plugin": "^4.0.1", 26 | "css-loader": "^0.28.9", 27 | "eventsource-polyfill": "^0.9.6", 28 | "express": "^4.14.1", 29 | "extract-text-webpack-plugin": "^3.0.2", 30 | "file-loader": "^1.1.6", 31 | "friendly-errors-webpack-plugin": "^1.1.3", 32 | "function-bind": "^1.1.0", 33 | "html-webpack-plugin": "^2.28.0", 34 | "http-proxy-middleware": "^0.17.3", 35 | "node-sass": "^4.5.0", 36 | "opn": "^5.2.0", 37 | "optimize-css-assets-webpack-plugin": "^3.2.0", 38 | "ora": "^1.1.0", 39 | "rimraf": "^2.6.0", 40 | "sass-loader": "^6.0.0", 41 | "semver": "^5.3.0", 42 | "url-loader": "^0.6.2", 43 | "vue-loader": "^14.1.1", 44 | "vue-style-loader": "^3.1.1", 45 | "vue-template-compiler": "^2.4.2", 46 | "webpack": "^3.10.0", 47 | "webpack-bundle-analyzer": "^2.2.1", 48 | "webpack-dev-middleware": "^2.0.4", 49 | "webpack-hot-middleware": "^2.16.1", 50 | "webpack-merge": "^4.1.1" 51 | }, 52 | "engines": { 53 | "node": ">= 4.0.0", 54 | "npm": ">= 3.0.0" 55 | }, 56 | "browserslist": [ 57 | "> 1%", 58 | "last 2 versions", 59 | "not ie <= 8" 60 | ] 61 | } 62 | -------------------------------------------------------------------------------- /examples/e-commerce/src/App.vue: -------------------------------------------------------------------------------- 1 | 161 | 162 | 171 | 172 | 173 | 313 | -------------------------------------------------------------------------------- /examples/e-commerce/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/vue-instantsearch-examples/19deb6668ff08c159cda175527b7797287771cac/examples/e-commerce/src/assets/logo.png -------------------------------------------------------------------------------- /examples/e-commerce/src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue'; 4 | import App from './App.vue'; 5 | import AlgoliaComponents from 'vue-instantsearch'; 6 | 7 | Vue.config.productionTip = false; 8 | Vue.use(AlgoliaComponents); 9 | 10 | // eslint-disable-next-line no-new 11 | new Vue({ 12 | el: '#app', 13 | template: '', 14 | components: { App }, 15 | }); 16 | -------------------------------------------------------------------------------- /examples/e-commerce/static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/vue-instantsearch-examples/19deb6668ff08c159cda175527b7797287771cac/examples/e-commerce/static/.gitkeep -------------------------------------------------------------------------------- /examples/multi-index/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["latest", { 4 | "es2015": { "modules": false } 5 | }] 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /examples/multi-index/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log 5 | yarn-error.log 6 | -------------------------------------------------------------------------------- /examples/multi-index/README.md: -------------------------------------------------------------------------------- 1 | # multi-index 2 | 3 | > Example of multi-index queries - Vue.js + Algolia 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | ``` 17 | 18 | For detailed explanation on how things work, consult the [docs for vue-loader](http://vuejs.github.io/vue-loader). 19 | -------------------------------------------------------------------------------- /examples/multi-index/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Example of multi-index queries - Vue.js + Algolia 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/multi-index/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-multi-index", 3 | "description": "Example of multi-index queries - Vue.js + Algolia", 4 | "version": "1.0.0", 5 | "author": "Raymond Rutjes ", 6 | "private": true, 7 | "scripts": { 8 | "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot", 9 | "build": "cross-env NODE_ENV=production webpack --progress --hide-modules" 10 | }, 11 | "dependencies": { 12 | "vue": "^2.2.1", 13 | "vue-instantsearch": "^1.4.0" 14 | }, 15 | "devDependencies": { 16 | "babel-core": "^6.0.0", 17 | "babel-loader": "^7.1.2", 18 | "babel-preset-latest": "^6.0.0", 19 | "cross-env": "^5.1.3", 20 | "css-loader": "^0.28.9", 21 | "file-loader": "^1.1.6", 22 | "node-sass": "^4.5.0", 23 | "sass-loader": "^6.0.6", 24 | "vue-loader": "^14.1.1", 25 | "vue-template-compiler": "^2.2.1", 26 | "webpack": "^3.10.0", 27 | "webpack-dev-server": "^2.2.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/multi-index/src/App.vue: -------------------------------------------------------------------------------- 1 | 92 | 93 | 102 | 103 | 230 | -------------------------------------------------------------------------------- /examples/multi-index/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import App from './App.vue'; 3 | import Plugin from 'vue-instantsearch'; 4 | 5 | Vue.use(Plugin); 6 | 7 | // eslint-disable-next-line no-new 8 | new Vue({ 9 | el: '#app', 10 | render: h => h(App), 11 | }); 12 | -------------------------------------------------------------------------------- /examples/multi-index/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-commonjs */ 2 | 3 | const path = require('path'); 4 | const webpack = require('webpack'); 5 | 6 | module.exports = { 7 | entry: './src/main.js', 8 | output: { 9 | path: path.resolve(__dirname, './dist'), 10 | publicPath: '/dist/', 11 | filename: 'build.js', 12 | }, 13 | module: { 14 | rules: [ 15 | { 16 | test: /\.vue$/, 17 | loader: 'vue-loader', 18 | options: { 19 | loaders: { 20 | // Since sass-loader (weirdly) has SCSS as its default parse mode, we map 21 | // the "scss" and "sass" values for the lang attribute to the right configs here. 22 | // other preprocessors should work out of the box, no loader config like this necessary. 23 | scss: 'vue-style-loader!css-loader!sass-loader', 24 | sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax', 25 | }, 26 | // other vue-loader options go here 27 | }, 28 | }, 29 | { 30 | test: /\.js$/, 31 | loader: 'babel-loader', 32 | exclude: /node_modules/, 33 | }, 34 | { 35 | test: /\.(png|jpg|gif|svg)$/, 36 | loader: 'file-loader', 37 | options: { 38 | name: '[name].[ext]?[hash]', 39 | }, 40 | }, 41 | ], 42 | }, 43 | resolve: { 44 | alias: { 45 | vue$: 'vue/dist/vue.esm.js', 46 | }, 47 | }, 48 | devServer: { 49 | historyApiFallback: true, 50 | noInfo: true, 51 | }, 52 | performance: { 53 | hints: false, 54 | }, 55 | devtool: '#eval-source-map', 56 | }; 57 | 58 | if (process.env.NODE_ENV === 'production') { 59 | module.exports.devtool = '#source-map'; 60 | // http://vue-loader.vuejs.org/en/workflow/production.html 61 | module.exports.plugins = (module.exports.plugins || []).concat([ 62 | new webpack.DefinePlugin({ 63 | 'process.env': { 64 | NODE_ENV: '"production"', 65 | }, 66 | }), 67 | new webpack.optimize.UglifyJsPlugin({ 68 | sourceMap: true, 69 | compress: { 70 | warnings: false, 71 | }, 72 | }), 73 | new webpack.LoaderOptionsPlugin({ 74 | minimize: true, 75 | }), 76 | ]); 77 | } 78 | -------------------------------------------------------------------------------- /examples/nuxt/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | node_modules 3 | 4 | # logs 5 | npm-debug.log 6 | 7 | # Nuxt build 8 | .nuxt 9 | 10 | # Nuxt generate 11 | dist 12 | -------------------------------------------------------------------------------- /examples/nuxt/README.md: -------------------------------------------------------------------------------- 1 | # nuxt-instantsearch 2 | 3 | > Nuxt.js integration with Vue InstantSearch 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | $ npm install # Or yarn install 10 | 11 | # serve with hot reload at localhost:3000 12 | $ npm run dev 13 | 14 | # build for production and launch server 15 | $ npm run build 16 | $ npm start 17 | 18 | # generate static project 19 | $ npm run generate 20 | ``` 21 | 22 | For detailed explanation on how things work, checkout the [Nuxt.js docs](https://github.com/nuxt/nuxt.js). 23 | -------------------------------------------------------------------------------- /examples/nuxt/nuxt.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-commonjs */ 2 | const resolve = require('path').resolve; 3 | 4 | module.exports = { 5 | modulesDir: resolve(__dirname, '../../node_modules/'), 6 | head: { 7 | title: 'nuxt-instantsearch', 8 | meta: [ 9 | { charset: 'utf-8' }, 10 | { name: 'viewport', content: 'width=device-width, initial-scale=1' }, 11 | { 12 | hid: 'description', 13 | name: 'description', 14 | content: 'Nuxt integration with Vue InstantSearch', 15 | }, 16 | ], 17 | }, 18 | plugins: ['~/plugins/vue-instantsearch'], 19 | }; 20 | -------------------------------------------------------------------------------- /examples/nuxt/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-instansearch", 3 | "version": "1.0.0", 4 | "description": "Nuxt integration with Vue InstantSearch", 5 | "license": "MIT", 6 | "scripts": { 7 | "dev": "nuxt", 8 | "build": "nuxt build", 9 | "start": "nuxt start", 10 | "generate": "nuxt generate" 11 | }, 12 | "dependencies": { 13 | "nuxt": "^1.3.0", 14 | "vue": "^2.5.13", 15 | "vue-instantsearch": "^1.4.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/nuxt/pages/index.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 24 | -------------------------------------------------------------------------------- /examples/nuxt/pages/search.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 20 | 21 | 58 | -------------------------------------------------------------------------------- /examples/nuxt/plugins/vue-instantsearch.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import InstantSearch from 'vue-instantsearch'; 3 | 4 | Vue.use(InstantSearch); 5 | -------------------------------------------------------------------------------- /examples/quick-start/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /examples/quick-start/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Welcome to Vue 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 36 | 37 | 38 |
39 | 40 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /examples/quick-start/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-simple", 3 | "description": "Simple example of using Algolia instantsearch with Vue.js in the browser.", 4 | "version": "0.0.0", 5 | "author": "Raymond Rutjes ", 6 | "private": true, 7 | "scripts": { 8 | "build": "[[ -f 'index.html' ]] && echo 'all good'" 9 | }, 10 | "dependencies": { 11 | "vue-instantsearch": "1.4.0" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/quick-start/styles.css: -------------------------------------------------------------------------------- 1 | #app { 2 | font-family: 'Avenir', Helvetica, Arial, sans-serif; 3 | -webkit-font-smoothing: antialiased; 4 | -moz-osx-font-smoothing: grayscale; 5 | color: #2c3e50; 6 | width: 1400px; 7 | margin: auto; 8 | } 9 | 10 | .ais-input { 11 | width: 100%; 12 | outline: none; 13 | font-size: 15px; 14 | padding: 7px; 15 | box-sizing: border-box; 16 | border: 2px solid lightgrey; 17 | border-radius: 2px; 18 | margin: 20px 0; 19 | margin-right: 5%; 20 | padding-left: 40px; 21 | } 22 | 23 | .ais-search-box__submit, .ais-clear { 24 | background: none; 25 | border: none; 26 | position: absolute; 27 | z-index: 30; 28 | top: 30px; 29 | } 30 | 31 | .ais-search-box__submit { 32 | left: 25px; 33 | } 34 | .ais-clear { 35 | right: 30px; 36 | } 37 | .ais-clear--disabled { 38 | display: none; 39 | } 40 | 41 | 42 | 43 | .ais-powered-by { 44 | float: right; 45 | margin-right: 10px; 46 | 47 | } 48 | 49 | .ais-powered-by svg { 50 | vertical-align: bottom; 51 | } 52 | 53 | .search-result { 54 | padding: 10px 20px 20px; 55 | width: 25%; 56 | border: solid 1px #EEE; 57 | box-shadow: 0 0 3px #f6f6f6; 58 | 59 | position: relative; 60 | border-radius: 3px; 61 | min-width: 220px; 62 | background: #FFF; 63 | 64 | display: inline; 65 | float: left; 66 | transition: all .5s; 67 | } 68 | 69 | .result__info { 70 | position: absolute; 71 | width: 100%; 72 | padding: 0px 20px 20px; 73 | bottom: 0; 74 | left: 0; 75 | } 76 | 77 | .result__image { 78 | margin-bottom: 100px; 79 | } 80 | 81 | .result__name { 82 | font-size: 14px; 83 | font-weight: bold; 84 | } 85 | 86 | .result__name em, .result__type em { 87 | font-style: normal; 88 | background: rgba(143, 187, 237, .1); 89 | box-shadow: inset 0 -1px 0 0 rgba(69, 142, 225, .8); 90 | } 91 | 92 | .result__type em { 93 | background: rgba(143, 187, 237, .1); 94 | border-radius: 0; 95 | box-shadow: inset 0 -1px 0 0 rgba(69, 142, 225, .8); 96 | } 97 | 98 | .result__price { 99 | font-size: 25px; 100 | font-weight: bold; 101 | position: absolute; 102 | right: 20px; 103 | bottom: 16px; 104 | } 105 | 106 | .result__type { 107 | color: #a2a2a2; 108 | font-size: 12px; 109 | } 110 | 111 | .result__rating { 112 | margin-top: 10px; 113 | } 114 | 115 | .result__star { 116 | width: 1em; 117 | height: 1em; 118 | } 119 | 120 | .result__star:before { 121 | content: '\2605'; 122 | color: #FBAE00; 123 | } 124 | 125 | .result__star--empty:before { 126 | content: '\2606'; 127 | color: #FBAE00; 128 | } 129 | -------------------------------------------------------------------------------- /examples/ssr/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { "modules": false }] 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /examples/ssr/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log 5 | yarn-error.log 6 | -------------------------------------------------------------------------------- /examples/ssr/README.md: -------------------------------------------------------------------------------- 1 | # example-ssr 2 | 3 | > An illustration of server side rendering with Algolia Vue InstantSearch. 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | ``` 17 | 18 | For detailed explanation on how things work, consult the [docs for vue-loader](http://vuejs.github.io/vue-loader). 19 | -------------------------------------------------------------------------------- /examples/ssr/build/webpack.base.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-commonjs */ 2 | const path = require('path'); 3 | 4 | module.exports = { 5 | devtool: '#cheap-module-source-map', 6 | output: { 7 | path: path.resolve(__dirname, '../dist'), 8 | publicPath: '/dist/', 9 | filename: '[name].js', 10 | }, 11 | module: { 12 | rules: [ 13 | { 14 | test: /\.vue$/, 15 | loader: 'vue-loader', 16 | }, 17 | { 18 | test: /\.js$/, 19 | loader: 'babel-loader', 20 | exclude: /node_modules/, 21 | }, 22 | { 23 | test: /\.(png|jpg|gif|svg)$/, 24 | loader: 'url-loader', 25 | options: { 26 | limit: 10000, 27 | name: '[name].[ext]?[hash]', 28 | }, 29 | }, 30 | { 31 | test: /\.css$/, 32 | use: ['vue-style-loader', 'css-loader'], 33 | }, 34 | ], 35 | }, 36 | }; 37 | -------------------------------------------------------------------------------- /examples/ssr/build/webpack.client.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-commonjs */ 2 | const webpack = require('webpack'); 3 | const merge = require('webpack-merge'); 4 | const baseConfig = require('./webpack.base.config.js'); 5 | const VueSSRClientPlugin = require('vue-server-renderer/client-plugin'); 6 | 7 | module.exports = merge(baseConfig, { 8 | entry: './src/main.client.js', 9 | plugins: [ 10 | // Important: this splits the webpack runtime into a leading chunk 11 | // so that async chunks can be injected right after it. 12 | // this also enables better caching for your app/vendor code. 13 | new webpack.optimize.CommonsChunkPlugin({ 14 | name: 'manifest', 15 | minChunks: Infinity, 16 | }), 17 | // This plugins generates `vue-ssr-client-manifest.json` in the 18 | // output directory. 19 | new VueSSRClientPlugin(), 20 | ], 21 | }); 22 | -------------------------------------------------------------------------------- /examples/ssr/build/webpack.server.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-commonjs */ 2 | const merge = require('webpack-merge'); 3 | const nodeExternals = require('webpack-node-externals'); 4 | const baseConfig = require('./webpack.base.config.js'); 5 | const VueSSRServerPlugin = require('vue-server-renderer/server-plugin'); 6 | 7 | module.exports = merge(baseConfig, { 8 | // Point entry to your app's server entry file 9 | entry: './src/main.server.js', 10 | 11 | // This allows webpack to handle dynamic imports in a Node-appropriate 12 | // fashion, and also tells `vue-loader` to emit server-oriented code when 13 | // compiling Vue components. 14 | target: 'node', 15 | 16 | // For bundle renderer source map support 17 | devtool: 'source-map', 18 | 19 | // This tells the server bundle to use Node-style exports 20 | output: { 21 | libraryTarget: 'commonjs2', 22 | }, 23 | 24 | // https://webpack.js.org/configuration/externals/#function 25 | // https://github.com/liady/webpack-node-externals 26 | // Externalize app dependencies. This makes the server build much faster 27 | // and generates a smaller bundle file. 28 | externals: nodeExternals({ 29 | // do not externalize dependencies that need to be processed by webpack. 30 | // you can add more file types here e.g. raw *.vue files 31 | // you should also whitelist deps that modifies `global` (e.g. polyfills) 32 | whitelist: /\.css$/, 33 | }), 34 | 35 | // This is the plugin that turns the entire output of the server build 36 | // into a single JSON file. The default file name will be 37 | // `vue-ssr-server-bundle.json` 38 | plugins: [new VueSSRServerPlugin()], 39 | }); 40 | -------------------------------------------------------------------------------- /examples/ssr/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-ssr", 3 | "description": "An illustration of server side rendering with Algolia Vue InstantSearch.", 4 | "version": "1.0.0", 5 | "author": "Raymond Rutjes ", 6 | "private": true, 7 | "scripts": { 8 | "build": "yarn run build:server && yarn run build:client", 9 | "build:client": "cross-env NODE_ENV=production webpack --config build/webpack.client.config.js --progress --hide-modules", 10 | "build:server": "cross-env NODE_ENV=production webpack --config build/webpack.server.config.js --progress --hide-modules" 11 | }, 12 | "dependencies": { 13 | "express": "^4.15.3", 14 | "vue": "^2.3.3", 15 | "vue-instantsearch": "^1.4.0", 16 | "vue-router": "^3.0.1", 17 | "vue-server-renderer": "^2.3.3" 18 | }, 19 | "devDependencies": { 20 | "babel-core": "^6.0.0", 21 | "babel-loader": "^7.1.2", 22 | "babel-preset-env": "^1.5.1", 23 | "cross-env": "^5.1.3", 24 | "css-loader": "^0.28.9", 25 | "file-loader": "^1.1.6", 26 | "node-sass": "^4.5.0", 27 | "sass-loader": "^6.0.6", 28 | "url-loader": "^0.6.2", 29 | "vue-loader": "^14.1.1", 30 | "vue-ssr-webpack-plugin": "^3.0.0", 31 | "vue-template-compiler": "^2.3.3", 32 | "webpack": "^3.10.0", 33 | "webpack-dev-server": "^2.4.5", 34 | "webpack-merge": "^4.1.0", 35 | "webpack-node-externals": "^1.6.0" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /examples/ssr/server.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-commonjs */ 2 | const express = require('express'); 3 | const server = express(); 4 | 5 | const template = require('fs').readFileSync( 6 | './src/index.template.html', 7 | 'utf-8' 8 | ); 9 | const serverBundle = require('./dist/vue-ssr-server-bundle.json'); 10 | const clientManifest = require('./dist/vue-ssr-client-manifest.json'); 11 | 12 | const { createBundleRenderer } = require('vue-server-renderer'); 13 | 14 | const renderer = createBundleRenderer(serverBundle, { 15 | runInNewContext: false, // recommended 16 | template, // (optional) page template 17 | clientManifest, // (optional) client build manifest 18 | }); 19 | 20 | // Serve static assets from ./dist on the /dist route. 21 | server.use('/dist', express.static('dist')); 22 | 23 | // inside a server handler... 24 | server.get('*', (req, res) => { 25 | const context = { url: req.url }; 26 | // No need to pass an app here because it is auto-created by the 27 | // executing the bundle. Now our server is decoupled from our Vue app! 28 | renderer.renderToString(context, (err, html) => { 29 | if (err !== null) { 30 | if (err.code === 404) { 31 | res.status(404).end('Page not found'); 32 | } else { 33 | res.status(500).end('Internal Server Error'); 34 | } 35 | 36 | // eslint-disable-next-line no-console 37 | console.log(err); 38 | } else { 39 | res.end(html); 40 | } 41 | }); 42 | }); 43 | 44 | // eslint-disable-next-line no-console 45 | console.log('Application is running on: http://localhost:8080'); 46 | 47 | server.listen('8080'); 48 | -------------------------------------------------------------------------------- /examples/ssr/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 12 | 41 | -------------------------------------------------------------------------------- /examples/ssr/src/Search.vue: -------------------------------------------------------------------------------- 1 | 18 | 80 | -------------------------------------------------------------------------------- /examples/ssr/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algolia/vue-instantsearch-examples/19deb6668ff08c159cda175527b7797287771cac/examples/ssr/src/assets/logo.png -------------------------------------------------------------------------------- /examples/ssr/src/index.template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Server Side Rendering example | Vue InstantSearch 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/ssr/src/main.client.js: -------------------------------------------------------------------------------- 1 | import { createApp } from './main'; 2 | 3 | // client-specific bootstrapping logic... 4 | 5 | const { app } = createApp(); 6 | 7 | // this assumes App.vue template root element has id="app" 8 | app.$mount('#app'); 9 | -------------------------------------------------------------------------------- /examples/ssr/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import App from './App.vue'; 3 | import InstantSearch from 'vue-instantsearch'; 4 | import { createRouter } from './router'; 5 | 6 | Vue.use(InstantSearch); 7 | 8 | export function createApp() { 9 | const router = createRouter(); 10 | const app = new Vue({ 11 | router, 12 | render: h => h(App), 13 | }); 14 | return { app, router }; 15 | } 16 | -------------------------------------------------------------------------------- /examples/ssr/src/main.server.js: -------------------------------------------------------------------------------- 1 | import { createApp } from './main'; 2 | 3 | export default context => 4 | // since there could potentially be asynchronous route hooks or components, 5 | // we will be returning a Promise so that the server can wait until 6 | // everything is ready before rendering. 7 | new Promise((resolve, reject) => { 8 | const { app, router } = createApp(); 9 | 10 | // set server-side router's location 11 | router.push(context.url); 12 | 13 | // wait until router has resolved possible async components and hooks 14 | router.onReady(() => { 15 | const matchedComponents = router.getMatchedComponents(); 16 | // no matched routes, reject with 404 17 | if (!matchedComponents.length) { 18 | // eslint-disable-next-line prefer-promise-reject-errors 19 | reject({ code: 404, context }); 20 | } 21 | 22 | // call asyncData() on all matched route components 23 | Promise.all( 24 | matchedComponents.map(Component => { 25 | if (Component.asyncData) { 26 | return Component.asyncData({ 27 | context, 28 | route: router.currentRoute, 29 | }); 30 | } 31 | return undefined; 32 | }) 33 | ) 34 | .then(() => { 35 | resolve(app); 36 | }) 37 | .catch(reject); 38 | }, reject); 39 | }); 40 | -------------------------------------------------------------------------------- /examples/ssr/src/router.js: -------------------------------------------------------------------------------- 1 | // router.js 2 | import Vue from 'vue'; 3 | import Router from 'vue-router'; 4 | import Search from './Search.vue'; 5 | 6 | Vue.use(Router); 7 | 8 | export function createRouter() { 9 | return new Router({ 10 | mode: 'history', 11 | routes: [ 12 | { path: '/', name: 'home', component: Search }, 13 | { path: '/search/:query?', name: 'search', component: Search }, 14 | ], 15 | }); 16 | } 17 | -------------------------------------------------------------------------------- /examples/vue-router/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["latest", { 4 | "es2015": { "modules": false } 5 | }] 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /examples/vue-router/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log 5 | yarn-error.log 6 | -------------------------------------------------------------------------------- /examples/vue-router/README.md: -------------------------------------------------------------------------------- 1 | # example-vue-router 2 | 3 | > Algolia search with Vue Router 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | ``` 17 | 18 | For detailed explanation on how things work, consult the [docs for vue-loader](http://vuejs.github.io/vue-loader). 19 | -------------------------------------------------------------------------------- /examples/vue-router/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | example-vue-router 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/vue-router/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-vue-router", 3 | "description": "Algolia search with Vue Router", 4 | "version": "1.0.0", 5 | "author": "Raymond Rutjes ", 6 | "private": true, 7 | "scripts": { 8 | "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot", 9 | "build": "cross-env NODE_ENV=production webpack --progress --hide-modules" 10 | }, 11 | "dependencies": { 12 | "qs": "^6.5.0", 13 | "vue": "^2.2.1", 14 | "vue-instantsearch": "1.4.0", 15 | "vue-router": "^3.0.1" 16 | }, 17 | "devDependencies": { 18 | "babel-core": "^6.0.0", 19 | "babel-loader": "^7.1.2", 20 | "babel-preset-latest": "^6.0.0", 21 | "cross-env": "^5.1.3", 22 | "css-loader": "^0.28.9", 23 | "file-loader": "^1.1.6", 24 | "node-sass": "^4.5.0", 25 | "sass-loader": "^6.0.6", 26 | "vue-loader": "^14.1.1", 27 | "vue-template-compiler": "^2.2.1", 28 | "webpack": "^3.10.0", 29 | "webpack-dev-server": "^2.2.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /examples/vue-router/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /examples/vue-router/src/Search.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 66 | -------------------------------------------------------------------------------- /examples/vue-router/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import VueRouter from 'vue-router'; 3 | import InstantSearch from 'vue-instantsearch'; 4 | import App from './App.vue'; 5 | import Search from './Search.vue'; 6 | import qs from 'qs'; 7 | 8 | Vue.use(InstantSearch); 9 | Vue.use(VueRouter); 10 | 11 | const router = new VueRouter({ 12 | routes: [ 13 | { 14 | name: 'search', 15 | path: '/search', 16 | component: Search, 17 | props: route => ({ queryParameters: route.query }), 18 | }, 19 | { path: '/', redirect: '/search' }, 20 | ], 21 | parseQuery(query) { 22 | return qs.parse(query); 23 | }, 24 | stringifyQuery(query) { 25 | const result = qs.stringify(query); 26 | 27 | return result ? `?${result}` : ''; 28 | }, 29 | }); 30 | 31 | // eslint-disable-next-line no-new 32 | new Vue({ 33 | el: '#app', 34 | render: h => h(App), 35 | router, 36 | }); 37 | -------------------------------------------------------------------------------- /examples/vue-router/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-commonjs */ 2 | 3 | const path = require('path'); 4 | const webpack = require('webpack'); 5 | 6 | module.exports = { 7 | entry: './src/main.js', 8 | output: { 9 | path: path.resolve(__dirname, './dist'), 10 | publicPath: '/dist/', 11 | filename: 'build.js', 12 | }, 13 | module: { 14 | rules: [ 15 | { 16 | test: /\.vue$/, 17 | loader: 'vue-loader', 18 | options: { 19 | loaders: { 20 | // Since sass-loader (weirdly) has SCSS as its default parse mode, we map 21 | // the "scss" and "sass" values for the lang attribute to the right configs here. 22 | // other preprocessors should work out of the box, no loader config like this necessary. 23 | scss: 'vue-style-loader!css-loader!sass-loader', 24 | sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax', 25 | }, 26 | // other vue-loader options go here 27 | }, 28 | }, 29 | { 30 | test: /\.js$/, 31 | loader: 'babel-loader', 32 | exclude: /node_modules/, 33 | }, 34 | { 35 | test: /\.(png|jpg|gif|svg)$/, 36 | loader: 'file-loader', 37 | options: { 38 | name: '[name].[ext]?[hash]', 39 | }, 40 | }, 41 | ], 42 | }, 43 | resolve: { 44 | alias: { 45 | vue$: 'vue/dist/vue.esm.js', 46 | }, 47 | }, 48 | devServer: { 49 | historyApiFallback: true, 50 | noInfo: true, 51 | }, 52 | performance: { 53 | hints: false, 54 | }, 55 | devtool: '#eval-source-map', 56 | }; 57 | 58 | if (process.env.NODE_ENV === 'production') { 59 | module.exports.devtool = '#source-map'; 60 | // http://vue-loader.vuejs.org/en/workflow/production.html 61 | module.exports.plugins = (module.exports.plugins || []).concat([ 62 | new webpack.DefinePlugin({ 63 | 'process.env': { 64 | NODE_ENV: '"production"', 65 | }, 66 | }), 67 | new webpack.optimize.UglifyJsPlugin({ 68 | sourceMap: true, 69 | compress: { 70 | warnings: false, 71 | }, 72 | }), 73 | new webpack.LoaderOptionsPlugin({ 74 | minimize: true, 75 | }), 76 | ]); 77 | } 78 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-examples", 3 | "repository": "https://github.com/algolia/vue-instantsearch-examples.git", 4 | "private": true, 5 | "scripts": { 6 | "lint": "eslint examples/**/*{.js,.vue} --ext .js,.vue", 7 | "build": "scripts/build.sh", 8 | "format": "prettier --write **/*.{js,vue,json}", 9 | "test": "yarn lint && yarn build" 10 | }, 11 | "workspaces": ["examples/*"], 12 | "devDependencies": { 13 | "babel-eslint": "8.2.3", 14 | "eslint": "4.19.1", 15 | "eslint-config-algolia": "13.1.0", 16 | "eslint-config-prettier": "2.9.0", 17 | "eslint-plugin-html": "4.0.3", 18 | "eslint-plugin-import": "2.12.0", 19 | "eslint-plugin-prettier": "2.6.0", 20 | "prettier": "1.11.1" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "pinVersions": true, 3 | "semanticCommits": true, 4 | "extends": [":library"], 5 | "depTypes": [ 6 | { 7 | "depType": "dependencies", 8 | "pinVersions": false, 9 | "semanticPrefix": "chore(deps): " 10 | } 11 | ], 12 | "automerge": true, 13 | "major": { 14 | "automerge": false 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # test all the examples 3 | echo "🏗 building all examples for production" 4 | 5 | for d in ./examples/*/ ; do 6 | ( 7 | cd "$d" && echo "👷‍♀️ building $PWD" && yarn build 8 | ) 9 | done 10 | --------------------------------------------------------------------------------