Vue js how to use route from index.html to docs folder - vue.js

I am new to Vue js, I am building a website using Vue js where I have a home page and docs folder which contains a lot of documents written and save in a .md file.
Now How I can on the navbar click redirect from my route.js page to docs .md files. Below is my folder structure.
I want to serve my homepage from main.js which is created using vue.js, and docs folder containing markdown files. Inside the docs folder have .vuepress with config.js which was configured to load index.md as the home page.
- docs
- guide
- index.md
- src
- components
- route.js
- vue.config.js
- main.js
Package.json
{
"scripts": {
"docs:build": "vuepress build docs",
"docs:dev": "vuepress dev docs",
"dev": "vuepress dev docs",
"build": "vuepress build docs",
"start": "vue-cli-service serve"
},
}

UPDATE: There are a few issues in your new code:
The app site uses Vue 2, which requires VuePress 1.x, but you have VuePress 2.x installed. If you want the docs and app source in the same project root with different NPM dependencies, you'd need something like a monorepo. To otherwise share NPM dependencies, you'll have to upgrade your app project to Vue 3 or downgrade VuePress. For the sake of example, install VuePress 1.x instead:
npm i -D vuepress#1
The VuePress port is not configured, so it starts at 8080 (until a free port is found). The docs link in your app is hard-coded to port 3000, so your VuePress should be configured to start there:
// docs/.vuepress/config.js
module.exports = {
port: 3000
}
The VuePress base URL is not configured, while your app assumes a base of /docs. Update your VuePress config to set the base URL acccordingly:
// docs/.vuepress/config.js
module.exports = {
base: '/docs/'
}
See GitHub PR
Answer to original question:
VuePress setup
Install vuepress in your project:
$ npm i -D vuepress # if using #vue/cli#4
$ npm i -D vuepress#next # if using #vue/cli#5
Add NPM scripts for Vuepress:
// package.json
{
"scripts": {
"docs:build": "vuepress build docs",
"docs:dev": "vuepress dev docs"
}
}
Create docs/.vuepress/config.js, and export a config object:
a. dest - Output the docs to your app's build output directory (dist for Vue CLI scaffolded projects).
b. base - Set the base URL so that it matches the intended destination on the server (e.g., set base URL to docs if deploying docs to https://example.com/docs/).
c. port - Set the port of the VuePress dev server (we'll configure Vue CLI's dev server to point there later).
d. themeConfig.nav - Set the top navbar links.
// docs/.vuepress/config.js
module.exports = {
dest: 'dist/docs',
title: 'My Project Docs',
base: '/docs/',
port: 3000,
themeConfig: {
nav: [
{
text: 'Guide',
link: '/guide/',
},
{
text: 'Main Project',
link: 'http://localhost:8080'
}
],
}
}
Add a docs link to your app's navbar (e.g., in App.vue):
<nav>
Docs 👈
<router-link to="/">Home</router-link>
...
</nav>
Create docs/README.md with the following contents:
# Hello World
Building
Build your app before the docs (especially if the app's build command deletes the output directory beforehand, as it does with Vue CLI):
$ npm run build
$ npm run docs:build
Development
If using Vue CLI, configure the dev server to redirect /docs to the VuePress dev server:
Configure Vue CLI's devServer.before:
// vue.config.js
module.exports = {
devServer: {
before: app => {
// point `/docs` to VuePress dev server, configured above
app.get('/docs', (req, res) => {
res.redirect('http://localhost:3000/docs')
})
}
}
}
Start the app's server and the docs server:
$ npm run serve
$ npm run docs:dev

You could add the the docs folder into the public directory, then link to /docs/guide/...

Related

Specify config file in nuxt 3

I have a Nuxt 3 application (3.0.0-rc.13) generating a static website, and have to deploy to two locations:
Firebase hosting
Amazon S3 bucket
Hosting on Firebase needs a baseUrl of /, and Amazon needs a different baseUrl (/2223/). This can be configured in nuxt config, however I cannot find an cli option to specify which config file to use.
I have tried these, but they just pick the default nuxt.config.ts.
nuxt generate -c nuxt.config.amazon.ts
nuxt generate --config-file nuxt.config.amazon.ts
I found this issue that added support to it for Nuxt 2, but I cannot find anything about it for Nuxt 3. Am I missing something or is it just not supported at all?
Thanks for the solution #kissu
If anyone faces the same problem, here is how I implemented it:
package.json scripts:
"generate": "cross-env DEPLOY_TARGET=default nuxt generate",
"generate:amazon": "cross-env DEPLOY_TARGET=amazon nuxt generate",
nuxt.config.ts
const getBaseUrl = () => {
const environment = process.env.DEPLOY_TARGET;
switch (environment) {
case "amazon":
return "/2223/";
default:
return "/";
}
};
export default defineNuxtConfig({
app: {
baseURL: getBaseUrl(),
},
});

Import a NPM module with a Nuxt Application in it

I would like to develop an NPM module that the user can import in his project.
The module contain a full administration panel created with Nuxt.
I don't want the user know anything about Nuxt, he just need to run a command like:
myppcommand start
and the application starts a server that is running the administration panel.
So my idea is to develop the NPM module with Nuxt. Generate all the static file inside ./dist folder and then myappcommand start will serve the app from node_modules.
// NPM Package myapp
// nuxt.config.js
export default {
components: [
{
path: '~/components/',
extensions: ['vue']
}
],
buildDir: './.nuxt',
srcDir: './src/',
target: 'static',
ssr: false,
generate: {
dir: './dist/'
}
};
// NPM Package myapp
npx nuxt generate
The command will generate all files in ./dist folder.
// User repo
npm install myapp
This will install myapp inside ./node_modules.
// User repo
cd node_modules/myapp/ && npx nuxt start -c nuxt.config.js
This will start the server and serve the app.
But is this the best way possible? It seems a bit hacky to me, to go inside node_modules, does somebody know a better way?
You could achieve this by declaring that your package has an executable file which starts Nuxt, in the bin property of package.json.
Firstly, create an executable script to start the app:
bin/start.js
#!/usr/bin/env node
// Based on node_modules/.bin/nuxt
global.__NUXT_PATHS__ = (global.__NUXT_PATHS__ || []).concat(__dirname)
require('#nuxt/cli').run(['start'])
.catch((error) => {
require('consola').fatal(error)
process.exit(2)
})
You can verify that this starts the app by running ./bin/start.js (provided you have made the file executable), or node ./bin/start.js.
Then, declare that your package should install this as a script when installed as a dependency:
package.json
{
"bin": {
"myapp": "bin/start.js"
}
}
When your package has been installed with npm install myapp, then node_modules/.bin/myapp will link to node_modules/myapp/bin/start.js and the user will be able to run it with npx myapp.

Environment variable in Vercel redirects

I want to deploy my create-react-app to Vercel.
I define my redirects in my now.json as follows:
{
"redirects": [
{ "source": "/api/(.*)", "destination": "BACKEND_URL/$1", "statusCode": 200 }
]
}
The destination URL depends on the environment variable BACKEND_URL, which is defined in the Vercel dashboard.
I am trying to replace the environment variable in the redirects in the following build command:
sed -i "s|BACKEND_URL|${BACKEND_URL}|g" now.json && yarn build
But unfortunately now.json doesn't seem to be available at build time:
09:54:44.243 sed: can't read now.json: No such file or directory
How to enable dynamic redirects in Vercel?
This is not possible since now.json is read to determine how to build so you can't dynamically generate it during a build.
Instead, consider using a framework like Next.js which provides a next.config.js that can read environment variables as defined in RFC 9081.
npm install next#canary react react-dom
// next.config.js
module.exports = {
experimental: {
async redirects() {
return [{
source: "/api/:path*",
destination: `${process.env.BACKEND_URL}/:path*`,
permanent: false,
}]
}
}
};
https://github.com/zeit/now/discussions/4351
I think this actually is possible.
If you are using create-react-app then you just need to preface your env var name with REACT_APP_. See here: https://create-react-app.dev/docs/adding-custom-environment-variables/
I am currently doing this with a websocket URL env var. I have named it REACT_APP_WS_URL and here is how I use it.
I have 2 different vercel files in the project:
vercel.staging.json which has this section:
"build": {
"env": {
"REACT_APP_WS_URL": "wss:staging.my-backend.com/socket"
}
}
vercel.live.json which has this section:
"build": {
"env": {
"REACT_APP_WS_URL": "wss:my-backend.com/socket"
}
}
I deploy to them with either of these commands:
vercel deploy --prod -A vercel.staging.json
vercel deploy --prod -A vercel.live.json
and in my code I can access process.env.REACT_APP_WS_URL anywhere.
I have not tried doing this with the Vercel dashboard env vars but it might be worth trying your original approach except rename your env var to REACT_APP_BACKEND_URL.
Note: my deployment commands only work when I don't assign domains to the project. If I assign domains to a project, they are automatically used for ALL --prod deploys, no matter what is in my alias field in the json config file.

How can I build my React Native Storybook to web?

I am running React Native Storybook which runs Storybook in the Native emulator.
In addition to the how React Native Storybook works currently, I would also like to build an instance of it for web as a reference companion to our app.
I am using "#storybook/react-native": "5.3.14". My stories are located at ./storybook.
Install react-native-web, #storybook/react and babel-plugin-react-native-web from npm in your project root.
Add a new configuration directory for Storybook, say ./.storybook-website. Inside this directory, add main.js. This creation would otherwise be done by the Storybook installation wizard.
my-app
├── .storybook-website
│   └── main.js
└── // .... rest of your app
Add the following content to main.js:
module.exports = {
stories: ['../storybook/stories/index.js'],
webpackFinal: async (config) => {
config.resolve.alias = {
...(config.resolve.alias || {}),
// Transform all direct `react-native` imports to `react-native-web`
'react-native$': 'react-native-web',
// make sure we're rendering output using **web** Storybook not react-native
'#storybook/react-native': '#storybook/react',
// plugin-level react-native-web extensions
'react-native-svg': 'react-native-svg/lib/commonjs/ReactNativeSVG.web',
// ...
};
// mutate babel-loader
config.module.rules[0].use[0].options.plugins.push(['react-native-web', { commonjs: true }]);
// console.dir(config, { depth: null });
return config;
},
};
Update the stories path in main.js to the location of your existing root story.
Finally add run scripts to your package.json:
"storybook:web": "start-storybook -p 6006 --config-dir ./.storybook-website",
"storybook-build:web": "build-storybook --config-dir ./.storybook-website --output-dir dist-storybook-website --quiet"
Presto! Run using yarn storybook:web. This will run storybook dev server, opening a browser showing what you usually would see in the device emulator.

404 when reloading a Vue website published to Github pages

I have deployed the contents of my /dist folder in the master branch of christopherkade.github.io, which has deployed my website succesfully.
But when I navigate using the navbar (christopherkade.com/posts or christopherkade.com/work) and reload the page I get an error by Github pages:
404 File not found
Note that my routing is done using Vue router like so:
export default new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/work',
name: 'Work',
component: Work
},
{
path: '/posts',
name: 'Posts',
component: Posts
},
{ path: '*', component: Home }
]
})
And my project is built like such:
build: {
// Template for index.html
index: path.resolve(__dirname, '../docs/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../docs'),
assetsSubDirectory: 'static',
assetsPublicPath: '/',
/**
* Source Maps
*/
productionSourceMap: true,
// https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map',
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
}
What could be causing this issue?
But when I navigate using the navbar (christopherkade.com/posts or
christopherkade.com/work) and reload the page 404 File not found
Let me explain why 404 File not found is being shown
When christopherkade.com/posts is triggered from web browser, the machine to which the domain christopherkade.com is mapped is contacted.
The path /posts is searched in its server. in your case, i believe the route for /posts doesn't exist in the server. As the result 404 is displayed
There are few ways to fix this
To prevent the browser from contacting the server when triggering the request christopherkade.com/posts, you can keep mode : 'hash' in your route configuration
How mode : 'hash' works? This is one way to fix your issue
mode : 'hash' makes use of default browser behavior which is to prevent http request from triggering the details that exists after #
As the result, when you trigger christopherkade.com/#/posts , christopherkade.com is being triggered by the browser and once response is received the /posts route from the route config is invoked.
Lets assume that you have control over the server and you are adamant
that you need # to be removed from the URL
Then what you could do is to configure server in such a way that server responds with the same page everytime any paths is being sent. Once response is received in the browser, route will automatically kicked off.
Even in your current program, the routeConfig gets kicked off when you click any links (like work,posts) in your page. This is because the browser behavior is not being invoked at this point.
In your case, you use github for hosting this app with mode: 'history' i myself have to look for a specific solution to workaround this. i will update my answer once i get it.
i hope this was useful.
You can fix this issue by a simple workaround. I combined all the insights from reading multiple issues about this and finally this is what helped me fix this problem.
Solution Logic - You just need a copy of index.html with the name 404.html in the dist folder
Steps to fix
Go to you package.json file, under scripts add a new script called "deploy" like below, you just need to execute this everytime after you build your page. It will automatically take care of the issue.
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"deploy": "cd dist && cp index.html 404.html && cd .. && gh-pages -d dist"
},
This will copy the index.html & rename it 404.html and pushes dist folder under the branch gh-pages and after that your script will appear in the vue ui like below
or
If you are using git subtree push --prefix dist origin gh-pages method to push, then edit the deploy script in package.json to below
"deploy": "cd dist && cp index.html 404.html
and then execute the below git command. PS, don't forget to execute this script before manually using npm script method or from the vue ui
git subtree push --prefix dist origin gh-pages
This actually happens since your browser makes a request to christopherkade.com/posts URL which doesn't exist (this route is defined in Vue application running from index.html).
If you were running your own server, you would probably configure it to render your index.html page for any request URI, so your Vue application would be loaded from any path and handle routing by itself.
Speaking of GitHub pages, you can't just configure them to act the same way I described, but fortunately, there is a workaround which uses custom 404 page:
https://github.com/rafrex/spa-github-pages
As a workaround, I duplicated the index.html and renamed it to 404.html.
In this way, if the page is reloaded, you still get the correct page however this is served through the 404.html file.
As a workaround I have created folders for each route (with a script) and placed the index.html in all of them.
404s still don't work.
If you use Nuxt, this fixes the problem.
layaouts/blank.vue
<template>
<nuxt />
</template>
pages/redirect.vue
<template>
<div></div>
</template>
<script>
export default {
layout: 'blank',
fetch({base, redirect, query}) {
const param = query.p
if (param === undefined) {
return redirect('/')
}
const redirectPath = '/' + param.replace(base, '')
return redirect(redirectPath)
}
}
</script>
static/404.html
<html>
<head>
<script>
var pathName = window.location.pathname;
var redirectPath = '/<repository-name>/redirect';
location.href = redirectPath + '?p=' + encodeURI(pathName);
</script>
</head>
</html>
https://gist.github.com/orimajp/2541a8cde9abf3a925dffd052ced9008
Very simple perfect solution just follow the below instruction
Add a _redirects file inside the /public folder like /public/_redirects
After that add /* /index.html 200 into the _redirects file
I think with this solution your redirect problem will be solved