Implementing Stripe on Nuxt App - StripeCheckout not found in 'vue-stripe-checkout' - javascript

I'm trying to implement stripe on my NuxtJS App but I'm facing this error :
StripeCheckout not found in 'vue-stripe-checkout'.
I was trying to follow along this tuto :
https://github.com/jofftiquez/vue-stripe-checkout#demo
Here is what I did so far :
Install vue-stripe-checkout package
Declare plugin in my Nuxt.config.js
plugins: [
{ src: "~/plugins/stripeCheckOut.js", ssr: false }
build: {
extend(config, ctx) {
config.module.rules.push({
enforce: "pre",
test: /\.(js|vue)$/,
loader: "eslint-loader",
exclude: /(node_modules)/,
options: {
fix: true
}
});
},
transpile: ["/plugins"]
}
};
Create a plugin
import Vue from 'vue'
import VueStripeCheckout from 'vue-stripe-checkout'
const options = {
key:
'MY KEY', // STRIPE_TOKEN,
locale: 'auto',
currency: 'EUR'
}
Vue.use(VueStripeCheckout, options)
And finaly call this new plugin in my component :
<template>
<div>
<h1>Voici un récapitulatif de votre commande:</h1>
<stripe-checkout
ref="checkoutRef"
:pk="publishableKey"
:items="items"
:success-url="successUrl"
:cancel-url="cancelUrl"
>
<template slot="checkout-button">
<button #click="checkout">
Shut up and take my money!
</button>
</template>
</stripe-checkout>
</div>
</template>
<script>
import { StripeCheckout } from 'vue-stripe-checkout'
export default {
name: 'RecapPrice',
components: {
StripeCheckout
},
data: () => ({
loading: false,
publishableKey: process.env.PUBLISHABLE_KEY,
items: [
{
sku: 'sku_FdQKocNoVzznpJ',
quantity: 1
}
],
successUrl: 'your-success-url',
cancelUrl: 'your-cancel-url'
}),
methods: {
checkout () {
console.log('coucou')
this.$refs.checkoutRef.redirectToCheckout()
}
}
}
</script>
If someone as already implemented Stripe in a Nuxt App, I'd get very happy to get some of your insights
Thanks a lot !

Related

Is it possible to make a library of Vue highcharts components?

I am just desperate for an answer but there's a hope to find the answer here.
I Used following stuff:
"vite": "^2.7.13",
"highcharts": "^9.3.3",
"highcharts-vue": "^1.4.0"
I would like to make a library of vue components including highcharts charts. I tried to make BarChart with rollup config like this:
import vue from "rollup-plugin-vue";
import typescript from "rollup-plugin-typescript2";
import resolve from "rollup-plugin-node-resolve";
import postcss from "rollup-plugin-postcss";
import dts from "rollup-plugin-dts";
import cleaner from "rollup-plugin-cleaner";
import commonjs from "#rollup/plugin-commonjs";
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
import image from '#rollup/plugin-image';
const plugins = [
resolve(),
typescript({
check: false,
useTsconfigDeclarationDir: true,
}),
vue({
preprocessStyles: true,
css: false,
template: {
isProduction: true,
},
}),
peerDepsExternal(),
commonjs(),
postcss({
extensions: [".css"],
}),
image(),
];
const AppChart = [
{
input: "./demo-v3/src/components/Chart.vue",
output: [
{
format: "esm",
file: "./demo-v3/lib/UI/AppChart/index.js",
},
],
external: ["#vue"],
plugins: [...plugins, commonjs({
namedExports: {
"node_modules/highcharts-vue/dist/highcharts-vue.min.js": ["Chart"],
},
}),],
},
];
const config = [...AppChart];
export default config;
My component BarChart.vue looks like this:
<template>
<div class="chart-wrapper">
<Chart :chart-options="lineChartOptions" />
</div>
</template>
<script setup lang="ts">
import Chart from "./CommonChart.vue";
const props = defineProps({
chartData: {
type: Object,
// eslint-disable-next-line #typescript-eslint/no-empty-function
default: () => {},
},
});
const exportingOptions = () => {
return {
buttons: {
contextButton: {
menuItems: [
"viewFullscreen",
"separator",
"downloadPNG",
"downloadPDF",
"printChart",
"separator",
"downloadCSV",
"downloadXLS",
],
},
},
};
};
let lineChartOptions = {
...props.chartData,
exporting: exportingOptions(),
credits: { enabled: false },
};
</script>
<style lang="scss">
.chart-wrapper {
padding: 15px;
width: 1140px;
height: 440px;
border: 1px solid #c4c4c4;
}
</style>
And there is a common chart component looks like this:
<template>
<highcharts class="hc" :options="chartOptions" />
</template>
<script setup lang="ts">
import { Chart as highcharts } from "highcharts-vue";
import Highcharts from "highcharts";
const props = defineProps({
chartOptions: {
type: Object,
// eslint-disable-next-line #typescript-eslint/no-empty-function
default: () => {},
},
});
</script>
It works when I use BarChart and doesn't work after bundling with rollup.
What can I do wrong?
my colleague found this guide with the setup which is worked for me.
I leave it here for who can't find the same:
https://dev.to/shubhadip/vue-3-component-library-270p
UPDATED:
https://devsday.ru/blog/details/73660 - vite can build lib out-of-box. I haven't tried this way but suspect it works well. As always, I should look throw documentation carefully

How to customize theme in Vuetify using Storybook 6?

I want to customize themes in Vuetify using Storybook 6 and I am using #socheatsok78/storybook-addon-vuetify package https://storybook.js.org/addons/#socheatsok78/storybook-addon-vuetify
I did exactly what documentation says but theme is still not working at all. I want to configure vuetify with custom properties and with my own color palette.
preview.js
import '!style-loader!css-loader!sass-loader!./main.scss';
import {
withVuetify,
withThemeProvider,
} from '#socheatsok78/storybook-addon-vuetify/dist/decorators';
import minifyTheme from 'minify-css-string';
export const globalTypes = {
theme: {
dark: false,
options: {
customProperties: true,
minifyTheme,
},
themes: {
light: {
primary: '#007BBF',
secondary: '#008574',
},
dark: {
primary: '#f099aa',
},
},
},
};
export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
};
export const decorators = [withThemeProvider, withVuetify];
main.js
const path = require('path');
module.exports = {
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.#(js|jsx|ts|tsx)'],
addons: [
'#storybook/addon-links',
'#storybook/addon-docs',
'#storybook/addon-essentials',
'#storybook/preset-scss',
'#socheatsok78/storybook-addon-vuetify',
],
webpackFinal: async (config) => {
config.module.rules.push({
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader',
{
loader: 'sass-resources-loader',
options: {
resources: path.resolve(__dirname, 'main.scss'),
},
},
],
sideEffects: true,
include: path.resolve(__dirname, '../'),
});
return config;
},
};
Ok I fixed the theme, you can find an tutorial how to do this and with all working code down below.
I found a great explanation here:
https://morphatic.com/2020/09/30/configuring-storybook-6-for-vue-2-vuetify-2-3/
preview.html
import '!style-loader!css-loader!sass-loader!./main.scss';
import { withVuetify } from '#socheatsok78/storybook-addon-vuetify/dist/decorators';
import vuetify from './vuetify';
import Vue from 'vue';
export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
};
export const decorators = [
(story, context) => {
const wrapped = story(context);
return Vue.extend({
vuetify,
components: { wrapped },
template: `
<v-app>
<v-container fluid>
<wrapped/>
</v-container>
</v-app>
`,
});
},
withVuetify,
];
main.js
I removed one line from addons
'#socheatsok78/storybook-addon-vuetify',
vuetify.js
import Vue from 'vue';
import Vuetify from 'vuetify';
import minifyTheme from 'minify-css-string';
import theme from './theme';
import LRU from 'lru-cache';
const themeCache = new LRU({
max: 10,
maxAge: 1000 * 60 * 60, // 1 hour
});
Vue.use(Vuetify);
export default new Vuetify({
theme: {
options: {
customProperties: true,
minifyTheme,
themeCache,
},
themes: {
light: theme,
},
},
});
theme.js
export default {
// ... other colors
primary: '#007BBF',
};
Theme works perfect now, only variables are not loaded correctly and I don't know how to solve this, you can read about it in the article comments

vue-splide only works in Nuxt dev environment

I am having issues trying to make vue-splide work outside of nuxt dev, after generating the static or the spa, it doesn't work properly.
Changing the target in nuxt.config.js from static to SPA doesn't solve the problem.
Instead of using nuxt generate I also tried nuxt build and the results are the same.
The two pictures are here:
The slider is working only in one of them, as it can be seen.
Any help on making it work properly so I can deploy the site?
nuxt.config.js
export default {
// Target: https://go.nuxtjs.dev/config-target
target: 'static',
// Global page headers: https://go.nuxtjs.dev/config-head
head: {
title: 'Visgrow Internships',
htmlAttrs: {
lang: 'en',
},
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' },
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
{ rel: 'preconnect', href: 'https://fonts.gstatic.com' },
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css2?family=Roboto:ital,wght#0,500;1,300;2,100&display=swap' },
],
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: [],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [{ src: '~/plugins/splide.client.js', ssr: false }],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [
// https://go.nuxtjs.dev/typescript
'#nuxt/typescript-build',
],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
'#nuxtjs/axios'
],
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {},
}
splide.client.js
import Vue from 'vue';
import VueSplide from '#splidejs/vue-splide';
// import '#splidejs/splide/dist/css/splide.min.css';
// Importing the original CSS does not change a thing. Also, I import the above CSS in the bellow css
import '../plugins-css/splide.css';
Vue.use(VueSplide);
new Vue({
el: '#app',
render: h => h(App),
});
Tried it on my side, working perfectly fine.
Install the package with either yarn or npm.
yarn add #splidejs/vue-splide
Setup the plugin in the usual way.
vue-splide.client.js
import VueSplide from '#splidejs/vue-splide'
import Vue from 'vue'
import '#splidejs/splide/dist/css/themes/splide-sea-green.min.css'
Vue.use(VueSplide)
Import the plugin in plugins, no need to use ssr: false (it actually does not exist anymore) nor mode since you went to suffix the file with client.js.
export default {
ssr: false,
target: 'static',
plugins: ['~/plugins/vue-splide.client.js'],
...
}
Then, using it in a view is perfectly fine, styling aside.
pages/index.vue
<template>
<div>
<splide class="custom">
<splide-slide>
<img src="https://source.unsplash.com/weekly?water" />
</splide-slide>
<splide-slide>
<img src="https://source.unsplash.com/weekly?fire" />
</splide-slide>
<splide-slide>
<img src="https://source.unsplash.com/weekly?earth" />
</splide-slide>
</splide>
</div>
</template>
<style scoped>
.splide__slide {
height: 50vh;
margin: 0 auto;
}
.custom {
height: 50vh;
width: auto;
}
</style>
For the project, I went with ssr: false and target: 'static' (PS: target: SPA does not exist) so, I then need to do
yarn generate
yarn start
And here is the result

Storybook + MDX

My .js stories show perfectly on storybook but .mdx stories do not show & I get no error as well
main.js
module.exports = {
addons: [
'#storybook/addon-docs/register',
'#storybook/addon-actions/register',
'#storybook/addon-links/register',
'#storybook/addon-knobs/register',
'#storybook/addon-storysource/register',
'#storybook/addon-viewport/register',
],
};
webpack.config.js
as suggested here https://www.npmjs.com/package/#storybook/addon-docs#manual-configuration
config.module.rules.push({
test: /\.(stories|story)\.mdx?$/,
use: [
{
loader: 'babel-loader',
options: {
plugins: ['#babel/plugin-transform-react-jsx'],
},
},
{
loader: '#mdx-js/loader',
options: {
compilers: [createCompiler({})],
},
},
],
});
config.module.rules.push({
test: /\.(stories|story)\.jsx?$/,
loader: require.resolve('#storybook/source-loader'),
exclude: [/node_modules/],
enforce: 'pre',
});
preview.js
addParameters({
docs: {
container: DocsContainer,
page: DocsPage,
},
});
function loadStories() {
const requires = [require.context('#rrc', true, /\.stories\.(js|mdx)$/)];
for (const req of requires) req.keys().forEach(filename => req(filename));
}
configure(loadStories, module);
Now I have 2 types of stories
story.mdx
import { Meta, Story } from '#storybook/addon-docs/blocks';
// Components
import Chips from '../';
<Meta title="AAAAAAAAA AAAAAA/Chip2" component={Chip} />
# Chip
I can define a story with the function imported from CSF:
And I can also embed arbitrary markdown & JSX in this file.
<Chip label="Basic" />
<Preview>
<Story name="all checkboxes">
<form>
<Chip label="Basic" />
</form>
</Story>
</Preview>
### Installing
A step by step series of examples that tell you how to get a development env running
and .js stories which are like
import React from 'react';
import { storiesOf } from '#storybook/react';
import { Chip } from '../../..';
storiesOf('Chip', module)
.addParameters({
component: Chip,
})
.add('Basic', () => <Chip label="Basic" />)
.add('Disabled', () => <Chip label="Disabled" disabled />)

How to embed React component on other sites?

I've created React application and I need to generate embed code to other websites. It's large app where I want to do only one component as a widget for other domains. I have read Writing embeddable Javascript plugin with React & Webpack and How to embed react component on other domains?. I set my webpack, but still can't render the widget on another domain.
This widget should:
be available via <script> tag, not iframe
show only one part of the app (path /referral), but not all app
The widget is a button and popup, which displays by click on the button.
Here is my webpack.config.js in client folder:
const path = require('path');
const bundleOutputDir = './referral';
const env = require('yargs').argv.env;
module.exports = env => {
const isDevBuild = !(env && env.prod);
if (env === 'build') {
mode = 'production';
} else {
mode = 'development';
}
return [
{
mode: mode,
entry: './src/components/early-referrals/Referral.js',
output: {
filename: 'widget.js',
path: path.resolve(bundleOutputDir),
library: 'Referral',
libraryTarget: 'umd',
umdNamedDefine: true
},
devServer: {
contentBase: bundleOutputDir
},
module: {
rules: [
{ test: /\.html$/i, use: 'html-loader' },
{
test: /\.css$/i,
use: [
'style-loader',
'css-loader' + (isDevBuild ? '' : '?minimize')
]
},
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader'
}
]
},
{
test: /(\.jsx|\.js)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
[
'#babel/env',
{
targets: {
browsers: ['ie 6', 'safari 7']
}
}
]
]
}
}
}
]
}
}
];
};
Here is component RegisterReferral.js, which is entry point in webpack:
import PopupRef from '../popup/PopupRef';
const RegisterReferral = ({
...
}) => {
const [...] = useState();
useEffect(() => {
...
}, []);
return (
<div>
// some styles for button that displays popup
<PopupRef />
</div>
);
};
const mapStateToProps = state => ({
...
});
export default connect(
mapStateToProps,
{ ... }
)(RegisterReferral);
PopupRef.js is a component with popup, which should displays on other websites within the button.
In the App.js, I have the route for this component that I want to create as an embeddable:
<Route exact path="/referral" component={RegisterReferral} />
And this is a way how I paste the code on another domain:
// the URL in script is an URL of bundle file from webpack
<html>
<head>
<script src="http://example.com/client/referral/widget.js" type="text/javascript"></script>
</head>
<body>
<p>Another website</p>
<div id='app'></div>
</body>
</html>
Also, I've tried to do entry point in webpack.config.js with Referral.js. And here is this component:
// Referral.js
import React from 'react';
import { render } from 'react-dom';
import App from './RegisterReferral.js';
render(<App />, document.getElementById('app'));
// At this case, webpack.config.js has 2 changes:
entry: './src/components/early-referrals/Referral.js',
output: {
...
library: 'Referral',
},
Nothing works. My component doesn't display on other websites.
Please help me to figure out what's wrong and how to embed one component (not all app) from React app on other websites.
Assume that you correctly config your webpack to bundle react js code
This is how I render the component in any page I want
Assume that I have this component
import React, {Component} from "react";
import {render} from "react-dom";
class LoginForm extends Component { }
render(<LoginForm/>, document.getElementById("loginForm")); // use render method
Edit:
Just saw your code I think you need also change the id in index.html
<div id="root"></div>
to
<div id="referral"></div>

Categories

Resources