I tried a official NextJS MDX-Blog example.
https://github.com/mdx-js/mdx/tree/master/examples/next
But what I'm not able to figure out is how do I setup the NextJS config to load images via webpack?
import img from "./image.jpg"
## Hallo Blogwelt
![My own Image]({img})
You can also use the /public directory to hold your images. For example, if you add an image at /public/image.jpg, you can reference the image in your blog post like this:
![Alt Text](/image.jpg)
Edit: https://nextjs.org/docs/basic-features/image-optimization#local-images
Imagine your next.config.js as something to append to an existing webpack.config behind the scenes. You won't have direct access to the webpack but you can extend it.
So in order to load images you'll need an appropriate image loader.
I found next-images easiest to use:
const withImages = require('next-images')
module.exports = withImages({
webpack(config, options) {
return config
}
})
then you can import:
import Img from "./image.jpg"
Hey thanks for the tip!
It's been a while since June and a gave it another try today and now it's working like expected from me.
I took the MDX/Next Example
Edited the next.config.js like so:
const withPlugins = require('next-compose-plugins');
const images = require('remark-images');
const emoji = require('remark-emoji');
const optimizedImages = require('next-optimized-images');
const withMDX = require('#zeit/next-mdx')({
extension: /\.mdx?$/,
options: {
mdPlugins: [images, emoji]
}
});
module.exports = withPlugins([
[
withMDX,
{
pageExtensions: ['js', 'jsx', 'md', 'mdx']
}
],
[optimizedImages]
]);
Now it works exactly like expected and in a Markdown file within the pages folder I'm able to do something like this:
import Layout from '../../components/Layout'
import Image from './catimage.jpg'
# Hey guys this is the heading of my post!
<img src={Image} alt="Image of a cat" />
Sorry I'm late, but with Next v11 you can directly import images.
That being said, you can add custom loaders for Webpack to modify your mdx files and use a custom component to process the image. e.g.:
// save this somewhere such as mdxLoader and
// add it to your webpack configuration
const replaceAll = require("string.prototype.replaceall");
module.exports = function (content, map, meta) {
return replaceAll(
map
content,
/\!\[(.*)\]\((.+)\)/g,
`<NextImage alt="$1" src={require('$2').default} />`
);
};
and process it:
// and reference this in your MDX provider
const components = {
NextImage: (props: any) => {
return <Image alt={props.alt || "Image"} {...props} />;
},
};
Now you can use markdown flavored images in your posts!
![my image](./image.png)
Include the ./ relative prefix, however.
I'm building a Next.js blog with MDX-Bundler. It allows you to use a remark plugin called remark-mdx-images which converts markdown flavored images into JSX images.
Below is an example configuration to get it to work
const {code} = await bundleMDX(source, {
cwd: '/posts/directory/on/disk',
xdmOptions: options => {
options.remarkPlugins = [...(options.remarkPlugins ?? []), remarkMdxImages]
return options
},
esbuildOptions: options => {
options.outdir = '/public/directory/on/disk/img'
options.loader = {
...options.loader,
'.jpg': 'file'
}
options.publicPath = '/img/'
options.write = true
return options
}
})
You can check out the following resources for detailed explanation on how to do it.
Images with MDX-Bundler
How I built the new notjust.dev platform with NextJS
If you installed the #next/mdx package you can use the <Image /> component Next.js provides:
// pages/cute-cat.mdx
import Image from "next/image";
import cuteCat from "./cute-cat.jpg";
# Cute cat
This is a picture of a cute cat
<Image src={cuteCat} />
Related
I would like to properly render a docx file in React JS with the correct formatting, as it would appear in Word or a similar service. Currently, when displaying the text, all formatting is removed and appears as plain text. I obtain the file from the server, and process it, by:
const url = "http://localhost:8080/files/aboutme.docx";
axios.get(url, {
responseType: 'arraybuffer',
}).then(response => {
var doc = new Docxtemplater(new PizZip(response.data), {
delimiters: {
start: 'ran',
end: 'ran'
}
});
var text = doc.getFullText();
setAboutMe(text);
})
I am using the Docxtemplater and PizZip libraries.
Docxtemplater is
a library to generate docx/pptx documents from a docx/pptx template
If you need to render a docx file I think you should use react-doc-viewer. Then you could write something like:
import DocViewer from "react-doc-viewer";
function App() {
const doc = [{ uri: "http://localhost:8080/files/aboutme.docx" }];
return <DocViewer documents={doc} />;
}
I am a newbie on Svelte and in coding in general. I'd prefer to learn SvelteKit (Svelte#Next) rather than sapper since that seems to be where Svelte is heading.
For my personal project, I need to support dynamic routing based on url slugs. How do I do that in SvelteKit? For example, if I have /blog directory and need to pull content based on its "id", how would I do that?
The part that I am having difficulty with is accessing the URL slug parameter.
Thanks in advance.
you can create a file with the [brackets] : touch src/routes/blog/[slug].svelte
And paste the following code
<script>
import { page } from '$app/stores';
</script>
{$page.params.slug}
Then navigate to your app http://localhost:3000/blog/123
You should see your result
In order to create content for the http://localhost:3000/blog page, you can modify src/routes/blog/index.svelte
As of SvelteKit 1.0 the path should be a directory in brackets, e.g. for /blog/<slug> you will add the following:
src/routes/blog/[slug]
|_ +page.js
|_ +page.svelte
Then in src/routes/blog/[slug]/+page.js you can add something like
export const load = ({ params }) => {
return {
slug: params.slug
}
}
which will return it as a data property to +page.svelte, so you can write something like:
<script>
export let data;
</script>
<h1>{data.slug}</h1>
Reference: https://kit.svelte.dev/docs/routing
Caveat - the info in my reply probably may not be valid as SvelteKit matures, but from experiments I have done thus far, this works:
Parameter based routing is similar to the sveltejs/sapper-template. You should learn how Sapper does it first. Lets say I have a route blog with a single param slug (/blog/page-1 & /blog/page-2)
Create a route component in routes/blog named [slug].svelte
Copy the content from the sveltejs/sapper-template example.
Rename the preload function to load with a single parameter such as ctx
Alter the return object to append your slug property to props
export async function load(ctx) {
let slug = ctx.page.params.slug
return { props: { slug }}
}
If your blog has multiple params for the slug (/blog/2021/01/29/this-is-a-slug), you can remove [slug].svelte and create a file name [...data].svelte and change your load method to:
export async function load(ctx) {
let [year, month, day, slug] = ctx.page.params.data;
return { props: { data: { year, month, day, slug }}}
}
Don't forget to define your data property as an object. Here's a typescript example:
<script lang="ts">
export let data: { slug: string, year: number, month: number, day: number };
</script>
From there use the values as {data.slug}, etc
Happy hacking
I also had some issues with the Typescript import so here is a complete Typescript example.
Structure:
src/routes/coins/[coin_name]
|_ +page.ts
|_ +page.svelte
+page.ts:
import type { PageLoad } from './$types';
export const load: PageLoad = ({ params }) => {
return {
name: params.coin_name
}
}
export interface CoinPage{
name: string
}
+page.svelte and the use of the data:
<script lang="ts">
import type { CoinPage } from "./+page";
export let data:CoinPage;
</script>
<h1>{data.name}</h1>
I have a create react app 3 project,
so I have in my src folders some js scripts using like:
import { Foo } from 'components/layout/Foo
Unfortunately, the testcafe compiler complains about it by default.
I read that maybe the solution was to create specify a custom tsconfig.json in which I declare
{
"compilerOptions": {
"baseUrl: "src"
}
}
But it does not work, apparently.
Thanks.
Sorry, indeed it is not a component file, but a utils one in the src directory.
in my foo_test.js I have
import { ROOT_PATH } from '../src/utils/config'
fixture("00 Home | Arriving to the Home").page(ROOT_PATH)
test('Default | leads to the home page', async t => {
const location = await t.eval(() => window.location)
await t.expect(location.pathname).eql('/home')
})
where utils/config is
import { getMobileOperatingSystem } from 'utils/mobile'
export const MOBILE_OS = getMobileOperatingSystem()
let CALC_ROOT_PATH
if (MOBILE_OS === 'ios') {
document.body.className += ' cordova-ios'
CALC_ROOT_PATH = window.location.href.match(/file:\/\/(.*)\/www/)[0]
}
export const ROOT_PATH = CALC_ROOT_PATH || 'http://localhost:3000/'
I have some images in a folder and I try to loop it. For example, a folder named "coupons" has some images like "coupon1.png","coupon2.png","coupon3.png"....
Then in one component, I try to make a function to import all the images and return
<img src={coupon1} alt='coupon1' className="slide" />
<img src={coupon2} alt='coupon2' className="slide" />
<img src={coupon3} alt='coupon3' className="slide" />
.....
May I know what would be a good way to do this? How to avoid import images one by one? And how to get the total number of the images files in the folder?
import coupon1 from '../assets/coupons/coupon1.png';
import coupon2 from '../assets/coupons/coupon2.png';
import coupon3 from '../assets/coupons/coupon3.png';
...
And how to loop them? I tried to use template string but it ends with string not variable so still not work. Thank you so much!
Oh and I just found a way like this:
const slides = Array(6).fill().map((item, i) => (
<img key={i} src={require(`../assets/coupons/coupon${i + 1}.png`)} className="slide" />
));
but I'm not sure is this a good way to do this? And what is this syntax of using require inside jsx? May I know is there any explanation about why using require here?
You have 3 options:
1) You can use webpack and generate alias with file list.
webpack.config.js:
const webpack = require('webpack');
const child_process = require('child_process');
let stdout = child_process.execSync("find . -regex '.*\\(png\\|jgeg\\)$'", {encoding: 'utf8'});
let files = stdout.split('\n');
module.exports = {
plugins = [
new webpack.DefinePlugin({
IMAGES: JSON.stringify(files),
}),
];
}
index.js:
Promise.all(
files.map(a => import(a))
).then(
filesSources => console.log(`DO something with array: ${filesSources}`)
);
2) You can require images with context:
index.js:
list = require.context('./', false, /\.(png|jpeg)$/);
3) You can use copyWebpackPLugin if you don't need to work with sources:
webpack.config.js:
const CopyWebpackPlugin = require('copy-webpack-plugin');
new CopyWebpackPlugin([
{from: './src/assets/images', to: 'images'},
]),
Note in 3) case image won't be processed by webpack loaders chain. In first 2 cases you need to add rule for FileLoader. You can find example of 3 cases at https://github.com/akoidan/pychat/tree/master/fe
I'm trying to develop PDfViewer Application using Mozilla's PDF.js (example here). It would be great if there is any github project as a reference.
Thanks inadvance!!
PDF.js with typings in Angualr 10
ng2-pdf-viewer is a great solution. I needed to use PDF.js directly as for the requirement to generate thumbnail in a service without creating a component.
This works as of Angular 10:
npm i pdfjs-dist
npm i #types/pdfjs-dist
Import and Usage. Note the GlobalWorkerOptions.workerSrc = pdfWorkerSrc;:
import { getDocument, GlobalWorkerOptions, PDFDocumentProxy, PDFRenderParams, version, ViewportParameters } from 'pdfjs-dist';
export class MyPdfService {
private document: Document;
constructor(#Inject(DOCUMENT) document) {
this.document = document;
const pdfWorkerSrc = `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/${version}/pdf.worker.min.js`;
GlobalWorkerOptions.workerSrc = pdfWorkerSrc;
}
// My use case demonstrating strongly typed usage.
public async pdfToImageDataURLAsync(pdfFile: File): Promise<string> {
const arrayBuffer = await new Response(pdfFile).arrayBuffer();
const canvas = this.document.createElement('canvas'),
ctx = canvas.getContext('2d') as CanvasRenderingContext2D,
data = arrayBuffer;
const pdf: PDFDocumentProxy = await getDocument(data).promise;
const page = await pdf.getPage(1);
const viewPortParams: ViewportParameters = { scale: 2 };
const viewport = page.getViewport(viewPortParams);
canvas.height = viewport.height;
canvas.width = viewport.width;
const renderContext: PDFRenderParams = {
canvasContext: ctx,
viewport: viewport
};
const renderedPage = await page.render(renderContext).promise;
const res = canvas.toDataURL();
if (pdf != null) pdf.destroy();
return res;
}
}
If it is not a must to use Mozilla's PDF.js then you can use ng2-pdf-viewer npm module which uses PDF.js in background. You can start of it with following steps
Install
npm install ng2-pdf-viewer --save
Note: For angular 4 or less use version 3.0.8
Then, import the module in app.module.js
import { PdfViewerModule } from 'ng2-pdf-viewer';
#NgModule({
imports: [BrowserModule, PdfViewerModule],
declarations: [AppComponent],
bootstrap: [AppComponent]
})
And then use it in your component
#Component({
selector: 'example-app',
template: `
<pdf-viewer [src]="pdfSrc"
[render-text]="true"
style="display: block;">
</pdf-viewer>
})
For more details, refer the below git URL and the demo URL.
https://github.com/VadimDez/ng2-pdf-viewer
https://vadimdez.github.io/ng2-pdf-viewer/
Hope this helps you.
If the requirement is to use pdfjs directly on angular, here is the relevant code
copy the 'web' and 'build' folders from https://github.com/mozilla/pdfjs-dist under your application's assets folder.
Get/Create your `Blob() object
this.http.get(url, { responseType: ResponseContentType.Blob }).map(
(res) => {
return new Blob([res.blob()], { type: fileType });
});
3.Create url using blob and supply to viewer.html
// myBlob object is created over http call response. See item 2.
const fileUrl = URL.createObjectURL(myBlobObject);
let myFileName = "sample";
var viewerUrl = `assets/pdfjs/web/viewer.html?file=${encodeURIComponent(fileUrl)}&fileName=${sample}.pdf`;
window.open(viewerUrl);
You may have to manually upgrade pdfjs if you follow this steps.
If you are looking to use an easier solution without all these manual steps, install https://www.npmjs.com/package/ng2-pdfjs-viewer and follow the instructions.
The usage would be as easy as
<ng2-pdfjs-viewer pdfSrc="report.pdf"></ng2-pdfjs-viewer>