-
Notifications
You must be signed in to change notification settings - Fork 273
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Doesn't work on the server side #19
Comments
@oliverox you can implement your own sprite behaviour via webpack.config.js ...
module: {
loaders: [
{
test: /\.svg/,
// define path to custom sprite module
loader: 'svg-sprite?spriteModule=' + path.resolve(__dirname, 'server-side-rendering-sprite-module.js')
}
]
} server-side-rendering-sprite-module.js // simple sprite implementation which renders into string
function Sprite() {
this.symbols = [];
}
Sprite.prototype.add = function(image) {
this.symbols.push(image);
};
Sprite.styles = ['position:absolute', 'width:0', 'height:0', 'visibility:hidden'];
Sprite.prototype.render = function() {
return [
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="'+ Sprite.styles.join(';') +'">',
'<defs>',
this.symbols.join(''),
'</defs>',
'</svg>'
].join('');
};
module.exports = new Sprite(); my-app.js require('./image.svg');
var sprite = require('./server-side-rendering-sprite-module');
var renderedSprite = sprite.render();
console.log(renderedSprite); |
@oliverox does it helped? |
@kisenka Thanks for the help in the right direction. I have not had enough time to implement it yet as I've been moving over the new year. Will try it soon. Thanks again. |
@kisenka I stumbled upon same problem. Could you please elaborate on process of implementing the server-sider rendering module for React app? My node app generates sprite and inlines it into html (this works well): app.use((req, res, next) => {
const html = renderToString(
<Root />
);
let renderedSprite = Root.sprite;
res.send(template({ html, env, renderedSprite }));
}); and my components looks like this import svg_aws from './img/aws.svg';
class Icon extends React.Component {
render() {
let { glyph } = this.props;
return (
<svg
className="icon"
width="81px"
height="81px"
dangerouslySetInnerHTML={{__html: '<use xlink:href="' + glyph + '"></use>'}}
/>
)
}
}
<Icon glyph={svg_react} /> The problem is that when webpack compiles it (with |
Well.. i came up with crappy solution actually: const sprite = require('../../utils/svg-server-rendering.js');
...
let ids = sprite.symbols.map(i => {
return i.match(/id="(.*?)"/g)
});
let arr = ids.map(j => j[0].replace('id=', '#').replace(/\"/g, ""))
arr.map(el => <Icon glyph={el} />) Pretty sure that it is not only ugly, but also wrong somewhere 😐 UPD:aaaand it does not work on webpack dev server |
Maybe wrong var reference? |
No, i map all of them and they all |
@olegakbarov sorry, I am vacation till 21 March so I can't help you now |
No problem, i'll write up if got some results on this. |
Also struggling with server-side rendering. Initially, the error I got was a type error because React is undefined. Found out that it seems it's the |
I believe for SSR, we need a node require hook that will generate the correct ID for a given path, then it should all work fine since the sprite will be loaded client-side. |
Sorry for delay. I am working on it |
@kisenka do you still intend to work on this? |
I've created the testcase https://github.com/kisenka/svg-sprite-loader-ssr-testcase for server-side rendering.
You will see that output from sprite loader which contains the whole sprite. |
Shouldn't something like SSR live in the default sprite impl? The very least it should do on a node environment it just return the symbol id (without using |
@danilobuerger you're right. Sprite loader firstly created for in browser usage, so it works with browser environment out of the box. I think it will be good if sprite loader will use environment specific sprite implementation which depends on |
Hmm, so what we need to consider is client-only and server+client (render server side, pick up on client side) and server-only setups. Probably need to also consider outputing to a svg file (see #23). Overall it might make more sense splitting this up in multiple loaders. One that returns symbol ids (or external ref + symbol ids) and builds the svg map. Another loader to include that svg map either as file or load it in dom or output it in some other way. client-onlyIf inline, return symbol id on require. Include svg map in dom, updateable (?). server-onlyIf inline, return symbol id on require. Output svg map so it can be rendered. client+serverIf inline, return symbol id on require. Output svg map so it can be rendered. Client should not include svg map in dom as its already present. Maybe it can updated it instead like |
Just as a heads-up, for my project, I switched to making a webpack bundle for the server as well (as per this article: http://jlongster.com/Backend-Apps-with-Webpack--Part-I) to avoid needing duplicate logic for every loader that node should know about. |
Hi everyone! I've run into a similar issue, however I didn't want to webpack my entire backend so I came up with a kinda hacky solution. I was already using ignore-styles as I import relevant stylesheets into my react components, so in order to generate the correct server side markup I just needed to add the following to my bootstrapping file: const path = require('path');
const crypto = require('crypto');
require('ignore-styles').default(['.scss', '.css', '.svg'], (module, filename) => {
const base = path.basename(filename);
if (base.indexOf('.svg') > 0) {
module.exports = '#' + crypto.createHash('md5').update(filename).digest("hex");
}
}); Note this works with the following webpack config: {
...
module: {
loaders: [
{
test: /\.svg$/,
loader: 'svg-sprite?' + JSON.stringify({
name: '[pathhash]',
prefixize: true
})
}
]
},
...
} I hope this helps somebody! 😃 |
I can confirm that the approach provided by @kisenka in #19 (comment) works for me. I had to make the webpack config for the However, I think that the approach outlined in #45 will be more efficient and easier to set up. |
Confirming @hyatt03's solution works well! Thanks for sharing. |
Hello!! Are there any updates on this? (as I see this to be a feature for 2.0). Thanks in advance! |
@lrojas94 work in progress, I planning to release alpha version on the next week.
Do you have concrete question about loader with React? |
Thing is I'm using a server side rendered Application, which is why this loader is failing when going through the app initialization. In the meantime, I managed to make it work by only requiring the plugin if Thanks for taking the time to look out my problem here 👍 |
@oliverox Hey guys svg-sprite-loader@2.0 with server side rendering is on the way, please read about it here #91 and take part in discussion/voting. Thanks! |
Check 2.0.1 release |
Thanks for the great work.
I'm trying to get this loader to work on server side as well. Since it's touches
document
directly, I guess getting it to work on the server is currently not possible. Can you please confirm?If that is the case, do you have any plans of making it to work on the server as well?
The text was updated successfully, but these errors were encountered: